我有一个Specialized
类,它从@classmethod
类继承Generic
并将一些字符串映射到方法:
class Generic(object):
@classmethod
def generate_static_data(cls):
return cls.field.upper()
class Specialized(Generic):
field = 'Some data'
MAPPING = {
# NameError: name 'Specialized' is not defined
'key': Specialized.generate_static_data,
}
def __init__(self):
for key, meth in Specialized.MAPPING.iteritems():
print(key, meth())
如何引用继承的方法?
Specialized
类名称引用它(可能是因为该类尚未完全解析,但是?):# NameError: name 'Specialized' is not defined
,NameError: name 'generate_static_data' is not defined
。Generic
类引用它,则cls
参数指向错误的类。编辑:显然可能会将引用编码为字符串,并且只在运行时将其展开,但我觉得这不必要地复杂:
MAPPING = {
'key': 'generate_static_data',
}
def __init__(self):
for key, meth in Specialized.MAPPING.iteritems():
print(key, getattr(Specialized, meth)())
此外,在现实世界项目中,这个例子来自,将字符串映射到字符串是默认的,我真的喜欢将一些字符串映射到callables的区别,而不是映射到恰好可解析为的另一个字符串可赎回的。
答案 0 :(得分:2)
我知道实现这一目标的最简单方法是:
class Generic(object):
@classmethod
def generate_static_data(cls):
return cls.field.upper()
class Specialized(Generic):
field = 'Some data'
def __init__(self):
for key, meth in Specialized.MAPPING.iteritems():
print(key, meth())
Specialized.MAPPING = {
'key': Specialized.generate_static_data,
}
基本上,定义 Specialized.MAPPING
后定义了Specialized
,因此您不会遇到NameError: name 'Specialized' is not defined
问题:
>>> Specialized()
('key', 'SOME DATA')
<__main__.Specialized object at 0x1049e9d50>
另一种方法是使用getattr
函数并在映射中引用方法名称"generate_static_data"
而不是方法对象本身。请注意,只有MAPPING
中的所有值都是Specialized
上的类方法(继承或其他)时,此特定实现才有效:
class Generic(object):
@classmethod
def generate_static_data(cls):
return cls.field.upper()
class Specialized(Generic):
field = 'Some data'
MAPPING = {
'key': 'generate_static_data',
}
def __init__(self):
for key, meth in Specialized.MAPPING.iteritems():
print(key, getattr(Specialized, meth)())
这导致相同的输出:
>>> Specialized()
('key', 'SOME DATA')
<__main__.Specialized object at 0x1065a2cd0>
就个人而言,我认为第一个解决方案更清晰,但第二个解决方案将所有内容都定义在Specialized
类中。