检查函数是否包含 pass
Checking whether function contains pass
我有一个 parent class P
和几个 child class。 parent class 包含方法 doSomething(x)
仅定义为:
def doSomething(self, x):
pass
现在,P
的一些子class可能已经实现了这个方法,有些还没有。有什么方法可以在运行时检查 doSomething(x)
是否除了 pass
之外什么都不做(例如,如果它已实现,则执行它,如果没有,则跳过它)?
由于您的父方法定义为
def doSomething(x):
pass
它什么都不做 - 只调用它而不是验证它是否被覆盖会更便宜。它将自动 "skipped" 因为它首先什么都不做。
也就是说,如果你真的想测试它,你可以这样做
if type(some_instance).doSomething is ParentClass.doSomething:
print('Not overriden')
else:
print('Function has been overriden, call it'):
some_instance.doSomething()
这里不需要做任何事情,只需在实例上调用doMethod()
。调用 no-op 方法的成本并不高,以至于检测 child class 何时实施覆盖将为您节省任何费用。
所以您的第一个选择是只调用方法,不用担心它是一个空方法。这就是 pass
是 for,给你一个什么都不做的简单 parent class 方法。
接下来,你说
Parent class contains method doSomething(x)
你可以用它来检测你是否还有那个方法;绑定方法的基础函数将是相同的 object:
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
这可以应用于本质上只 returns 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
的函数。
我有一个 parent class P
和几个 child class。 parent class 包含方法 doSomething(x)
仅定义为:
def doSomething(self, x):
pass
现在,P
的一些子class可能已经实现了这个方法,有些还没有。有什么方法可以在运行时检查 doSomething(x)
是否除了 pass
之外什么都不做(例如,如果它已实现,则执行它,如果没有,则跳过它)?
由于您的父方法定义为
def doSomething(x):
pass
它什么都不做 - 只调用它而不是验证它是否被覆盖会更便宜。它将自动 "skipped" 因为它首先什么都不做。
也就是说,如果你真的想测试它,你可以这样做
if type(some_instance).doSomething is ParentClass.doSomething:
print('Not overriden')
else:
print('Function has been overriden, call it'):
some_instance.doSomething()
这里不需要做任何事情,只需在实例上调用doMethod()
。调用 no-op 方法的成本并不高,以至于检测 child class 何时实施覆盖将为您节省任何费用。
所以您的第一个选择是只调用方法,不用担心它是一个空方法。这就是 pass
是 for,给你一个什么都不做的简单 parent class 方法。
接下来,你说
Parent class contains method
doSomething(x)
你可以用它来检测你是否还有那个方法;绑定方法的基础函数将是相同的 object:
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
这可以应用于本质上只 returns 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
的函数。