簡體   English   中英

通過傳遞相同類型的對象在 Python 中初始化類實例

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM