除了在实例上调用doMethod() 之外,这里无需执行任何操作。调用无操作方法的成本并不高,以至于检测子类何时实现了覆盖可以为您节省任何事情。
所以你的第一选择是只调用方法,不要担心它是一个空方法。这就是pass 的作用,为您提供一个简单的父类方法,它什么都不做。
接下来,你说
父类包含方法doSomething(x)
你可以用它来检测你是否还有那个方法;绑定方法的底层函数将是同一个对象:
hook = instance.doSomething
if hook.__func__ is ParentClass.doSomething:
# they didn't override the method, so nothing needs to be done.
同样,我不知道为什么有人会想要这样做,因为该测试不会比仅使用 instance.doSomething() 为您节省任何东西。
接下来,仅由语句pass 组成的函数将始终编译为相同的字节码;它与return None 的字节码相同。如果必须知道函数是否为空,请比较字节码:
_RETURN_NONE = (lambda: None).__code__.co_code
def is_pass(f):
return f.__code__.co_code == _RETURN_NONE
这可以应用于本质上只返回None 并且不执行任何其他操作的任何函数或方法。
演示:
>>> class P:
... def doSomething(self, x):
... pass
...
>>> class Child1(P):
... def doSomething(self, x):
... print("We are doing something with {!r}!".format(x))
...
>>> class Child2(P):
... pass
...
>>> instance1 = Child1()
>>> instance2 = Child2()
>>> instance1.doSomething(42)
We are doing something with 42!
>>> instance2.doSomething(42)
>>> instance1.doSomething.__func__ is P.doSomething
False
>>> instance2.doSomething.__func__ is P.doSomething
True
>>> is_pass(instance1.doSomething)
False
>>> is_pass(instance2.doSomething)
True
>>> def unrelated_function():
... return 42
...
>>> def another_unrelated_function():
... pass
...
>>> is_pass(unrelated_function)
False
>>> is_pass(another_unrelated_function)
True
注意is_pass() 如何作用于任何使用pass 的函数。