Python类方法和(?)实例方法

2024-09-30 08:33:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我编写了一个Python类来解析一种特殊的文本格式。你知道吗

class Parser(object):

   def __init__(self):
       # Initialize parser instance


   def parseFile(self , filename):
       pass

   def modifyParser(self , *args , **kwargs):
       pass 

   #Classmethod has same name as instance method - this does not work.
   @classmethod 
   def parseFile(cls , filename)
       parser = Parser( )
       return parser.parseFile( filename )

如前所述,可以使用modifyParser方法修改解析器—但在大多数情况下,我只使用来自Parser.__init__()的解析器实例。我希望能够做到这一点:

# Parse file using 'custom' parser:
parser = Parser( )
parser.modifyParser( ... )
result = parser.parseFile("file.input")


# Parse using the default parser - do not explicitly instantiate an object:
result = Parser.parseFile("file.input")

这要求parseFile( )方法既可以作为实例方法调用(使用self),也可以作为类方法调用。这可能吗?糟糕的形式?你知道吗


Tags: 方法instanceselfparser解析器objectinitdef
2条回答

你得用两个不同的名字。在Python中,由于它的动态性质,在C++中没有操作符重载,当一个函数具有不同参数的同名时。你知道吗

在脚本中说def时,告诉Python“将下面的对象(函数对象)设置为这个名称”。因此,在代码中只需重新定义引用classmethod的名称,实例方法函数对象就会丢失。你知道吗

解决方案:instace方法和class方法使用不同的名称。你知道吗

如果我是你,我会提供两种不同的功能:

  1. mymodule.Parser().parseFile()(实例方法),和
  2. mymodule.parseFile()(使用默认实例的模块级函数)。你知道吗

例如,标准^{}模块就是这样,其中有json.JSONDecoder().decode()json.loads()。提供两个不同的函数使代码不那么模棱两可,更显式,更可预测(在我看来)。你知道吗

然而,是的:你想做的是可能的。您必须使用__get__实现自己的descriptor。举个例子:

from functools import partial

class class_and_instance_method(object):

    def __init__(self, func):
        self.func = func

    def __get__(self, obj, type=None):
        first_arg = obj if obj is not None else type
        return partial(self.func, first_arg)

class Parser(object):

    @class_and_instance_method
    def parseFile(self):
        if isinstance(self, type):
            print('using default parser')
        else:
            print('using the current instance')

>>> Parser.parseFile()
using default parser

>>> p = Parser()
>>> p.parseFile()
using the current instance

相关问题 更多 >

    热门问题