[英]Initialize a class instance in Python by passing an object of the same type
在 Python 的 pathlib 模塊中,您可以從另一個 Path 創建一個 Path 對象,它們將是等效的:
p = Path('some/path')
p2 = Path(p)
p == p2
# True
我有一個 File 類,我想實現同樣的行為,如果我將 File 對象傳遞給 File 構造函數,它只會返回傳入的原始對象。這樣做的正確方法是什么? 我是否需要覆蓋__new__
方法來實現這一點?
正如@db 在評論中提到的,您可以“提取數據並創建一個新實例”。 這恰好是Path
使用@classmethod
s 的方式。 這是來自源代碼的關鍵函數(為了清晰起見,這里簡化了),它是從__new__
:
@classmethod
def _parse_args(cls, args):
parts = []
for a in args:
if isinstance(a, PurePath): # <--- Here
parts += a._parts # <---
else:
a = os.fspath(a)
if isinstance(a, str):
parts.append(str(a))
else:
raise TypeError()
return cls._flavour.parse_parts(parts)
然后p == p2
返回True
因為類的__eq__
定義,盡管p2
不是原始對象。
如果您真的希望構造函數返回原始對象,則必須覆蓋__new__
方法:
def __new__(cls, *args):
if isinstance(args[0], File):
return args[0]
instance = super().__new__(cls, *args)
# do initialization
return instance
請注意,您不能使用__init__
因為即使沒有創建新實例,它也會被調用。
更簡潔的解決方案是使用返回實例或新實例的函數:
def File(*args):
if isinstance (args[0], File_):
return args[0]
return File_(*args)
其中File_
是原始類
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.