提问人:opnightfall1771 提问时间:10/29/2021 更新时间:10/29/2021 访问量:759
在 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__
答:
1赞
jdaz
10/29/2021
#1
正如 @d.b 在评论中提到的,您可以“提取数据并创建一个新实例”。这恰好是如何使用 s。这是来自源代码的关键函数(为清楚起见,此处简化),该函数从以下位置调用:Path
@classmethod
__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
评论
0赞
opnightfall1771
10/31/2021
很有帮助,谢谢!我最终实现了一个解决方案,提取数据并创建一个新实例。
1赞
nadapez
10/29/2021
#2
如果你真的希望构造函数返回原始对象,那么你必须重写方法:__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_
评论
p is p2
False
str(some_str) is some_str