如何在 python 中克服 "classmethod is not callable"
How to overcome "classmethod is not callable" in python
看完Various errors in code that tries to call classmethods,
,
和其他人很明显 Python class 方法不可调用。 “为什么”似乎没有得到很好的回答,只是说不需要它显然是不正确的,正如关于这个主题的许多问题所表明的那样。
无论如何,我有一个 XML,在同一位置使用了许多不同的标签,每个标签都需要基本相似但又不同的处理方式。我的想法是为个别案例设置一个 base class 和 subclasses,每个案例都能够解析自己的部分(元素)并使用它们进行操作。像这样(简体):
import xml.etree.ElementTree as ET
class base():
parsers = dict()
@classmethod
def parseXml(cls, x:str):
parser = base.parsers.get(x)
parser(cls, x) # different class, but same base (and all called cls elements are only in base class)
# or parser(el)
class derivedOne(base):
def __init__(self):
self.one = None
@classmethod
def parseXml(cls, x:str):
d1 = derivedOne()
d1.one = 'one+'+x
base.parsers['xmlTagOne']=parseXml
class derivedTwo(base):
def __init__(self):
self.two = None
@classmethod
def parseXml(cls, x:str):
d2 = derivedTwo()
d2.two = 'two+'+x
base.parsers['xmlTagTwo']=parseXml
if __name__ == "__main__":
base.parseXml('xmlTagOne')
base.parseXml('xmlTagTwo')
已找到解析器,但无法调用。
当然,所有的构造函数都可以从一个地方用一些 if/else 逻辑调用,但这不是很优雅,最重要的是它不允许(正如我计划的那样)添加额外的 handler/parser class不改变基数 class...
有什么方法可以保留这个“在单个 class 中添加新标签的解析”吗?
您可以使用 __init_subclass__
在 base.parsers
中存储对新子 class 的引用。
class Base:
parsers = dict()
@classmethod
def parseXml(cls, x:str):
parser = base.parsers.get(x)
parser(cls, x)
def __init_subclass__(cls, /, tag, **kwargs):
super().__init_subclass__(**kwargs) # removed ...(cls, ...
Base.parsers[tag] = cls
class DerivedOne(Base, tag="xmlTagOne"):
def __init__(self):
self.one = None
@classmethod
def parseXml(cls, x:str):
...
class DerivedTwo(Base, tag="xmlTagTwo"):
def __init__(self):
self.two = None
@classmethod
def parseXml(cls, x:str):
...
if __name__ == "__main__":
base.parsers['xmlTagOne'].parseXml(some_string)
base.parsers['xmlTagTwo'].parseXml(some_other_string)
Base.__init_subclass__
在子 class 创建后立即被调用,基 class 列表中的任何关键字参数传递给 __init_subclass__
。每个 subclass 保存到 Base.parsers
带有指定的标签。
注意:我在这里完全忽略了您是否应该使用 classes 和 class 方法的问题。
看完Various errors in code that tries to call classmethods,
无论如何,我有一个 XML,在同一位置使用了许多不同的标签,每个标签都需要基本相似但又不同的处理方式。我的想法是为个别案例设置一个 base class 和 subclasses,每个案例都能够解析自己的部分(元素)并使用它们进行操作。像这样(简体):
import xml.etree.ElementTree as ET
class base():
parsers = dict()
@classmethod
def parseXml(cls, x:str):
parser = base.parsers.get(x)
parser(cls, x) # different class, but same base (and all called cls elements are only in base class)
# or parser(el)
class derivedOne(base):
def __init__(self):
self.one = None
@classmethod
def parseXml(cls, x:str):
d1 = derivedOne()
d1.one = 'one+'+x
base.parsers['xmlTagOne']=parseXml
class derivedTwo(base):
def __init__(self):
self.two = None
@classmethod
def parseXml(cls, x:str):
d2 = derivedTwo()
d2.two = 'two+'+x
base.parsers['xmlTagTwo']=parseXml
if __name__ == "__main__":
base.parseXml('xmlTagOne')
base.parseXml('xmlTagTwo')
已找到解析器,但无法调用。
当然,所有的构造函数都可以从一个地方用一些 if/else 逻辑调用,但这不是很优雅,最重要的是它不允许(正如我计划的那样)添加额外的 handler/parser class不改变基数 class...
有什么方法可以保留这个“在单个 class 中添加新标签的解析”吗?
您可以使用 __init_subclass__
在 base.parsers
中存储对新子 class 的引用。
class Base:
parsers = dict()
@classmethod
def parseXml(cls, x:str):
parser = base.parsers.get(x)
parser(cls, x)
def __init_subclass__(cls, /, tag, **kwargs):
super().__init_subclass__(**kwargs) # removed ...(cls, ...
Base.parsers[tag] = cls
class DerivedOne(Base, tag="xmlTagOne"):
def __init__(self):
self.one = None
@classmethod
def parseXml(cls, x:str):
...
class DerivedTwo(Base, tag="xmlTagTwo"):
def __init__(self):
self.two = None
@classmethod
def parseXml(cls, x:str):
...
if __name__ == "__main__":
base.parsers['xmlTagOne'].parseXml(some_string)
base.parsers['xmlTagTwo'].parseXml(some_other_string)
Base.__init_subclass__
在子 class 创建后立即被调用,基 class 列表中的任何关键字参数传递给 __init_subclass__
。每个 subclass 保存到 Base.parsers
带有指定的标签。
注意:我在这里完全忽略了您是否应该使用 classes 和 class 方法的问题。