我有一些來自庫/包的 Python 類、Say Class1、、Class2等。Class3我想用一些常見的功能擴展所有的類。如果我單獨擴展每個類,我們會引入大量冗余并打破“不要重復自己”的首字母縮寫詞。所以,我的想法是有一個Base類并使用它擴展其他類。例如:
class Base:
def __init__(self):
# I want self.base_attr_1, self.base_attr_2 and so on...
def base_method_1(self, *args, **kwargs):
pass
def base_method_2(self, *args, **kwargs):
pass
# and so on...
所以我們可以使用多重繼承來擴展Class1,Class2等等。說,
class Class1(Class1, Base):
pass
class Class2(Class2, Base):
pass
# and so on...
所以最后當我創建一個物件Class1等Class2時,我可以使用Base類的屬性和方法。喜歡;
class_1 = Class1(*args, **kwargs)
print(class_1.base_attr_1)
print(class_1.base_attr_2)
class_1.base_method_1(*args, **kwargs)
class_2.base_method_2(*args, **kwargs)
# and so on..
請解釋如何實作Class1等Class2,以擴展Base類。
非常感謝任何幫助。謝謝你。
uj5u.com熱心網友回復:
按照您的描述,您將有兩種可能性來處理您的問題:
- 元類
- 裝飾師
如果我是你,我會嘗試這樣的事情(裝飾器解決方案):
from functools import wraps
def deco(cls):
def test(x):
return x**2
d = {k:v for k,v in locals().items() if k != "cls"}
@wraps(cls)
def wrapper(*args, **kwargs):
o = cls(*args, **kwargs)
#o.test = test # setattr(o,"test", test) will be better solution,
# if you have more elements, which you'd like to add
# generalized :
# ============
for k,v in d.items(): setattr(o,k,v)
return o
return wrapper
@deco
class A(object):
pass
a = A()
print(a.__dict__)
print(a.test(10))
結果:
{'test': <function test at 0x02843C70>}
100
uj5u.com熱心網友回復:
當您有這樣的繼承設定時:
class MyClass1(Base, ExternalClass1):
呼叫super().__init__()將呼叫Base.__init__()(可能是第一個繼承的類),因此僅初始化Base. 您可以在同一繼承“級別”上顯式呼叫所有祖先的 init 函式,如下所示:
class MyClass1(Base, ExternalClass1):
def __init__(self) -> None:
Base.__init__(self)
ExternalClass1.__init__(self)
這將從Base和初始化屬性ExternalClass1。
例子:
class ExternalClass1():
def __init__(self) -> None:
self.external_attr_1 = "external attr"
def external_func1(self):
print("external_func1")
class Base():
def __init__(self) -> None:
self.base_attr_1 = "base attr"
def base_method_1(self):
print("base_method_1")
class MyClass1(Base, ExternalClass1):
def __init__(self) -> None:
Base.__init__(self)
ExternalClass1.__init__(self)
self.my_attr_1 = "my class attr"
self.external_func1()
self.base_method_1()
self.my_class_1_func()
print(self.external_attr_1)
print(self.base_attr_1)
print(self.my_attr_1)
def my_class_1_func(self):
print("my_class_1_func")
cl1 = MyClass1()
輸出:
external_func1
base_method_1
my_class_1_func
external attr
base attr
my class attr
Note however that self is now shared between all 3 classes, which can cause clashes. Another pattern is of course to go for composition, and have the external class be a property of MyClass1. This is both safer and introduces less coupling.
EDIT: If you need the same class-name, then you can reference it with the module-name - but I don't think it is very good practice.
import external
...
class MyClass1(Base, external.MyClass1):
def __init__(self) -> None:
Base.__init__(self)
external.MyClass1.__init__(self)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/448605.html
標籤:Python python-3.x
