我希望这会奏效:
class A(object):
@classmethod
def do_it(cls, spam, eggs):
if spam in A.ways_to_do_it:
A.ways_to_do_it[spam](eggs)
super(A, cls).do_it(spam, eggs)
@staticmethod
def do_it_somehow(eggs):
...
@staticmethod
def do_it_another_way(eggs):
...
ways_to_do_it = {
'somehow': do_it_somehow,
'another_way': do_it_another_way,
}
但它引发了TypeError: 'staticmethod' object is not callable
。我想检查staticmethod
以找出一些东西,但它是内置的。我希望它清楚我想在这里实现的目标。
你有什么想法怎么做得很好吗?我知道让这些@staticmethod
全局解决问题,但这在我的模块中会很混乱。
P上。 S. do_it_somehow
和do_it_another_way
将仅从A.do_it
调用。
答案 0 :(得分:4)
Python具有 descriptor 对象的概念,它们是至少具有__get__
方法的对象。当从类或实例中检索这些对象时,这些对象的行为会有所不同(调用它们的__get__
方法。)
@staticmethod
装饰器在具有静态方法行为的描述符中转换后续函数声明 - 但只有在将对象作为类属性检索时,所述行为才可用。上面的代码直接引用了对象。
因为你也有其他(类)方法让你的字典工作,你会更好 在类创建之后检索yoiur所需的方法,以便通过描述符协议检索每个方法:
class A(object):
@classmethod
def do_it(cls, spam, eggs):
if spam in A.ways_to_do_it:
A.ways_to_do_it[spam](eggs)
super(A, cls).do_it(spam, eggs)
@staticmetod
def do_it_somehow(eggs):
...
@staticmetod
def do_it_another_way(eggs):
...
A.ways_to_do_it = {
'somehow': A.do_it_somehow,
'another_way': A.do_it_another_way,
}
您可以在创建类之前检索静态方法,调用do_it_another_way.__get__(object, None)
- 因为它不需要类引用(但仍需要一个有效的类作为第一个参数)。但是如果你希望你的字典也指向定义的类方法,那么它们肯定必须在类创建之后获取:在创建类之前,Python无法创建一个“绑定类方法”。
在类体内创建对类/静态方法的其他直接引用:
class A(object):
@staticmethod
def foo(): ...
bar = foo
因为以这种方式,bar也将通过描述符协议获取。但由于你有一个间接字典,你必须自己处理描述符__get__
。
检查http://docs.python.org/2/reference/datamodel.html#implementing-descriptors以获取更多信息。 (这就是classmethod,staticmethod装饰器所做的,因为你也想知道)。
答案 1 :(得分:2)
试试这样:
class A(object):
@classmethod
def do_it(cls, spam, eggs):
if spam in A.ways_to_do_it:
A.ways_to_do_it[spam](eggs)
super(A, cls).do_it(spam, eggs)
@staticmethod
def do_it_somehow(eggs):
...
@staticmethod
def do_it_another_way(eggs):
...
A.ways_to_do_it = {
'somehow': A.do_it_somehow,
'another_way': A.do_it_another_way,
}
在完成类的构造之前引用类是很棘手的,因此在类定义结束后立即添加内容是最简单的。