我正在做一個類,它將成為另一個類的基礎,我想禁止在某些情況下覆寫某些方法,而我只是不知道該怎么做。
uj5u.com熱心網友回復:
您正在尋找super() 函式
uj5u.com熱心網友回復:
在python中,函式只是類的成員。你可以替換它們(什么是猴子補丁)來做一些完全不同的事情。
因此,即使不是子類的代碼也可以替代類函式來做不同的事情。
您可以對函式進行命名 - 但這也是可以規避的 - 它們也可以被猴子修補:
class p:
def __init__(self):
pass
def __secret(self):
print("secret called")
def __also_secret(self):
print("also_secret called")
def not_secret(self):
def inner_method():
print("inner called")
inner_method()
class r(p):
def __secret(self): # override existing function
print("overwritten")
演示:
a = p()
b = r()
# get all the respective names inside the class instance
c = [n for n in dir(a) if n.startswith("_p__")]
d = [n for n in dir(b) if n.startswith("_r__")]
# call the hidden ones and monkey patch then call again
for fn in c:
q = getattr(a, fn)
q() # original executed although "hidden"
q = lambda: print("Monkey patched " fn)
q() # replaced executed
# call the hidden ones and monkey patch then call again
for fn in d:
q = getattr(b, fn)
# original executed although "hidden"
q = lambda: print("Monkey patched " fn)
q() # replaced executed
# call public function
a.not_secret()
try:
# a.inner_method() # does not work
a.not_secret.inner_method() # does also not work as is it scoped inside
except AttributeError as e:
print(e)
a.not_secret = lambda: print("Monkey patched")
a.not_secret()
輸出:
also_secret called # name mangled called
Monkey patched _p__also_secret # patched of name mangled called
secret called # name mangled called
Monkey patched _p__secret # patched of name mangled called
Monkey patched _r__secret # overwritten by subclass one called
inner called # called the public that calls inner
'function' object has no attribute 'inner_method' # cannot get inner directly
Monkey patched
如果您想要此功能,您需要使用不同的語言 - 而不是 python。
uj5u.com熱心網友回復:
一種方法是使用“類裝飾器”來比較類本身及其父類的方法。這也可以使用__init_subclass__。我將向你們展示:
類裝飾器:
from inspect import isfunction
def should_not_override_parents_method(cls):
parents_methods = set(k for k, v in cls.__base__.__dict__.items() if isfunction(v))
class_methods = set(k for k, v in cls.__dict__.items() if isfunction(v))
diff = parents_methods & class_methods
if diff:
raise Exception(f"class {cls.__name__} should not implement parents method: "
f"'{', '.join(diff)}'")
return cls
class A:
def fn_1(self):
print("A : inside fn_1")
@should_not_override_parents_method
class B(A):
def fn_1(self):
print("B : inside fn_1")
def fn_2(self):
print("B : inside fn_2")
輸出:
Traceback (most recent call last):
File "<>", line 21, in <module>
class B(A):
File "<>", line 10, in should_not_override_parents_method
raise Exception(f"class {cls.__name__} should not implement parents method: "
Exception: class B should not implement parents method: 'fn_1'
__init_subclass__:
from inspect import isfunction
class A:
def __init_subclass__(cls, **kwargs):
parents_methods = set(k for k, v in cls.__base__.__dict__.items() if isfunction(v))
class_methods = set(k for k, v in cls.__dict__.items() if isfunction(v))
diff = parents_methods & class_methods
if diff:
raise Exception(f"class {cls.__name__} should not implement parents method: "
f"'{', '.join(diff)}'")
def fn_1(self):
print("A : inside fn_1")
class B(A):
def fn_1(self):
print("B : inside fn_1")
def fn_2(self):
print("B : inside fn_2")
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/346222.html
下一篇:JavaFx,如何在樹表視圖中正確覆寫:getChildren()和getChildren().add(newNode)
