我可以指定另一个类的实例方法作为我的方法的变量吗?

发布于 2024-11-04 05:44:54 字数 1729 浏览 3 评论 0原文

我对 python 还比较陌生,有 1-2 年的独立学习时间,并且正在努力改进我的代码结构,因此我正在重构我编写的一些旧程序。在一个程序中,我定义了几种写入文件的方法。第一个使用“write”来转储巨大的 http 响应。第二种使用“写入行”来转储各种派生列表,例如链接列表、表格或其他提取的数据。

我最初考虑了文件的命名:

    @property
    def baseFilename(self):
        unacceptable = re.compile(r'\W+')
        fname = re.sub(unacceptable,'-',self.myUrl)
        t = datetime.datetime.now()
        dstring = "%s%s%s%s%s%s" % (t.year, t.month, t.day, t.hour, t.minute, t.second)
        fullname = fname + '_' + dstring + '.html'
        return fullname

但是我在每个写入方法中都有大量冗余代码块:

    def writeFile(self, someHtml, writeMethod=write, prefix="RESPONSE_"):
        '''The calling functions will supply only the data to be written and 
           static prefixes, e.g. "full_" for the entire http-response.
        '''

       fullpath = self.myDump + prefix + self.baseFilename
       with open(fullpath, 'w') as h:
           h.write(someHtml)
           h.close()
       print "saved %s" % fullpath
       return fullpath

    def writeList(self, someList, prefix="mechList_"):
        '''Like write file but for one of the many lists outputted.  
           How do I refactor this, since redundant?
        '''

        fullpath = self.myDump + prefix + self.baseFilename
        with open(fullpath, 'w') as h:
            h.writelines(someList)
            h.close()
        print "saved %s" % fullpath
        return fullpath

我希望能够向每个函数添加一个变量来指定要使用的写入方法,例如( writeMethod=写入行)。我考虑过只传递一个字符串并使用其中一个黑魔法函数——我猜是 exec()——但这不可能是正确的,因为似乎没有人使用这些函数。整个示例可能相对愚蠢,因为我可以解决它,但我决定我会从了解如何传递这些实例方法中受益(这是正确的术语吗?)。这和绑定、解绑有关系吗?我需要一个好的答案是传递“write”、“writelines”等所需的语法。可以很简单:writeMethod = insert_your_syntax_here。不过,希望有更多的解释或指导。谢谢。

I'm still relatively new to python, 1-2 years of solo-learning, and am trying to improve my code structure so I'm refactoring some old programs I wrote. In one program, I defined a couple of methods for writing files. The first uses, "write" to dump a huge http-response. The second uses "writelines" to dump various derived lists, e.g. lists of links, or forms, or other extracted data.

I'd originally factored out the naming of the file:

    @property
    def baseFilename(self):
        unacceptable = re.compile(r'\W+')
        fname = re.sub(unacceptable,'-',self.myUrl)
        t = datetime.datetime.now()
        dstring = "%s%s%s%s%s%s" % (t.year, t.month, t.day, t.hour, t.minute, t.second)
        fullname = fname + '_' + dstring + '.html'
        return fullname

But I have a large redundant block of code in each write method:

    def writeFile(self, someHtml, writeMethod=write, prefix="RESPONSE_"):
        '''The calling functions will supply only the data to be written and 
           static prefixes, e.g. "full_" for the entire http-response.
        '''

       fullpath = self.myDump + prefix + self.baseFilename
       with open(fullpath, 'w') as h:
           h.write(someHtml)
           h.close()
       print "saved %s" % fullpath
       return fullpath

    def writeList(self, someList, prefix="mechList_"):
        '''Like write file but for one of the many lists outputted.  
           How do I refactor this, since redundant?
        '''

        fullpath = self.myDump + prefix + self.baseFilename
        with open(fullpath, 'w') as h:
            h.writelines(someList)
            h.close()
        print "saved %s" % fullpath
        return fullpath

I'd like to be able to add a variable to each function that specifies the write method to use, e.g. (writeMethod=writelines). I considered just passing in a string and using one of the black-magic functions-- exec() I guess-- but that can't possibly be right since no one ever seems to use those functions. This whole example may be relatively silly, since I could just work around it, but I decided I'd benefit from knowing how to pass these sorts of instance-methods (is that the right term?). Is this related to binding and unbinding? All I need for a good answer is the syntax required to pass 'write,' 'writelines' etc. Could be simple as: writeMethod = insert_your_syntax_here. Would love additional explanation or guidance though. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

百变从容 2024-11-11 05:44:54

您可以从对象获取“绑定方法”,然后可以将其作为函数调用,而无需引用该对象。

f = obj.method
f(args)
# is equivalent to
obj.method(args)

但是,这对您来说没有用,因为您创建了只想在方法中使用的对象 - 您不能将其作为绑定方法传递到那里。您可以分解完整路径的创建,尽管这只能节省一半的冗余。一种选择(我认为有点过分)是传递一个回调,该回调返回用于写入的函数。

另一种选择是使用装饰器来提取所有公共部分并将其余部分推入回调中,即装饰函数:

def uses_file(prefix_default):
    def decorator(f):
        @functools.wraps(f)
        def decorated(self, data, prefix=prefix_default):
            fullpath = obj.myDump + prefix + obj.baseFilename
            with open(fullpath, 'w') as h:
                f(h, data, prefix)
            print "saved", % fullpath
            return fullpath
        return decorated
    return decorator

# ...

@uses_file(default_prefix="RESPONE_")
def writeFile(self, someHtml, prefix):
   '''...'''
   h.write(someHtml)

@uses_file(default_prefix="mechList_")
def writeList(self, someList, prefix):
    '''...'''
    h.writelines(someList)

You can get a "bound method" from an object, which is then callable as a function without having a reference to the object.

f = obj.method
f(args)
# is equivalent to
obj.method(args)

However, that's not useful for you, as you create the object you want to use only in the method - you can't pass it in there as bound method. You can factor out the creation of fullpath, although this only saves you half of the redundancy. One option, which I'd consider overkill, would be passing a callback which return the function to use for writing.

Another option would be a decorator to factor out all the common parts and push the rest into a callback, the decorated function:

def uses_file(prefix_default):
    def decorator(f):
        @functools.wraps(f)
        def decorated(self, data, prefix=prefix_default):
            fullpath = obj.myDump + prefix + obj.baseFilename
            with open(fullpath, 'w') as h:
                f(h, data, prefix)
            print "saved", % fullpath
            return fullpath
        return decorated
    return decorator

# ...

@uses_file(default_prefix="RESPONE_")
def writeFile(self, someHtml, prefix):
   '''...'''
   h.write(someHtml)

@uses_file(default_prefix="mechList_")
def writeList(self, someList, prefix):
    '''...'''
    h.writelines(someList)
も星光 2024-11-11 05:44:54

有不同的方法可以做到这一点,例如使用 lambda:

def writeFile(self, someHtml, writeMethod=lambda f, data: f.write(data), 
              prefix="RESPONSE_"):
    '''The calling functions will supply only the data to be written and 
       static prefixes, e.g. "full_" for the entire http-response.
    '''

   fullpath = self.myDump + prefix + self.baseFilename
   with open(fullpath, 'w') as h:
       writeMethod(h, someHtml)
       h.close()
   print "saved %s" % fullpath
   return fullpath

There are different ways of doing this, for instance using lambdas:

def writeFile(self, someHtml, writeMethod=lambda f, data: f.write(data), 
              prefix="RESPONSE_"):
    '''The calling functions will supply only the data to be written and 
       static prefixes, e.g. "full_" for the entire http-response.
    '''

   fullpath = self.myDump + prefix + self.baseFilename
   with open(fullpath, 'w') as h:
       writeMethod(h, someHtml)
       h.close()
   print "saved %s" % fullpath
   return fullpath
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文