认为它被视为类方法的假设是错误的;<__main__.B object at 0x7f532970f340>
是类的instance,not是类的<class '__main__.B'>
.
方法是实例方法by default,需要@staticmethod
或@classmethod
才能偏离该默认设置.*args
将以实例方法的实例、类方法的类或静态方法的类开始.因为您没有使用这两个修饰符中的任何一个,所以它被视为一个实例方法,您可以说"自动生成"该实例.
虽然我会说这个模式看起来不是特别讨好,但一个更充实的例子来演示这些差异;(交换B
‘S METHOD
,看看每个函数的输出是什么样子.)
def some_function(*args, **kwargs):
print(args, kwargs)
@staticmethod
def some_static_function(*args, **kwargs):
print(args, kwargs)
def some_instance_function(self, *args, **kwargs):
print(self, args, kwargs)
@classmethod
def some_class_function(cls, *args, **kwargs):
print(cls, args, kwargs)
class A(object):
METHOD = None
def run(self, *args, **kwargs):
self.METHOD(*args, **kwargs)
class B(A):
METHOD = some_function
# Demo
instance_of_b = B()
instance_of_b.run("arg",kwarg="kwarg")
你会得到;
some_function
个
(<__main__.B object at 0x000002ED9340C190>, 'arg') {'kwarg': 'kwarg'}
some_static_function
个
('arg',) {'kwarg': 'kwarg'}
some_instance_function
个
<__main__.B object at 0x0000021F3E07C190> ('arg',) {'kwarg': 'kwarg'}
some_class_function
个
<class '__main__.B'> ('arg',) {'kwarg': 'kwarg'}
最后要考虑的是,将所有这些都考虑在内,并且不得不使用run
本身的实例方法格式,这是一个棘手的问题.请注意,如果将其设置为类方法,则some_instance_function
个将停止工作.它必须是实例方法,才能允许METHOD
根据METHOD
想要解释它的方式来解释调用它的self
.在run
是实例方法的情况下,METHOD
可以自由地对调用self
做它想做的事情.
另一方面,名称self
是约定的;任何名称都可以用于第一个参数.如果在run
中使用self
的元数令人困惑,您可以将其称为其他名称,即以下代码的工作原理相同.
class A(object):
METHOD = None
def run(caller, *args, **kwargs):
caller.METHOD(*args, **kwargs)