冷冻数据级Pathlib。类似Path的初始化
我有这个数据级:
@dataclass(frozen=True)
class CacheSchema:
id_key: str
snapshot_key: str | None
version: str = Info.Versions.schema_cache
我想以相同的方式初始化它pathlib.path.path
做到了,因此要么传递所需的参数或已经初始化的cacheschemachema
对象。从我有限的理解来看,我认为我必须自定义__ new __()
,所以我做到了,但是我不能完全按照path
做到这一点,因为数据级而且我不应该在创建后更改价值。因此,我想到了:
def __new__(cls, *args, **kwargs):
if len(args) == 1 and type(args[0]) is cls:
return cls.__new__(cls, args[0].id_key, args[0].snapshot_key, args[0].version)
return super(CacheSchema, cls).__new__(cls)
我的逻辑是:如果传递给定args的普通参数<代码> __ INT __ INT __(),否则请解开现有对象并回忆__ __ new __()
with打开的值。
我的问题是cls .__ new __(Cls,args [0] .id_key,args [0] .snapshot_key,args [0] .version)
不做我以为会做的事( __新的__
递归但具有不同的args)。
运行此
schema= CacheSchema('a', 'b', 'c')
schema2 = CacheSchema(schema)
加薪
File "D:/x/y/z/main.py", line 10, in <module>
schema2 = CacheSchema(schema)
TypeError: CacheSchema.__init__() missing 1 required positional argument: 'snapshot_key'
I have this dataclass:
@dataclass(frozen=True)
class CacheSchema:
id_key: str
snapshot_key: str | None
version: str = Info.Versions.schema_cache
and I would like to initialize it the same way pathlib.Path
does it, so either pass the required arguments or an already initialized CacheSchema
object. From my limited understanding I figured I would have to customize __new__()
, so I did, however I can't do it exactly as Path
does it because the dataclass is frozen and I'm not supposed to change the values after creation. So I came up with this:
def __new__(cls, *args, **kwargs):
if len(args) == 1 and type(args[0]) is cls:
return cls.__new__(cls, args[0].id_key, args[0].snapshot_key, args[0].version)
return super(CacheSchema, cls).__new__(cls)
My logic was: if normal arguments are passed call __init__()
with the given args, otherwise unpack the existing object and recall __new__()
with the unpacked values.
My issue is that cls.__new__(cls, args[0].id_key, args[0].snapshot_key, args[0].version)
doesn't do what I thought it would do (call __new__
recursively but with different args).
Running this
schema= CacheSchema('a', 'b', 'c')
schema2 = CacheSchema(schema)
raises
File "D:/x/y/z/main.py", line 10, in <module>
schema2 = CacheSchema(schema)
TypeError: CacheSchema.__init__() missing 1 required positional argument: 'snapshot_key'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
__ Init __
在__新__
之后调用。创建本质上是:
因此,您不能重新包装
args
。另请参见: python:override __init__ ___new__
pathlib.path.path.path.path.path.path.path.path.pathlib. like intantiation
与您的数据级不同,
pathlib.path
没有带有所需参数的__ INIT __
方法。它的
__新__
方法调用其他类方法_FROM_PARTS
1 1 dosself = object .__ new __ new __(cls)
,然后设置self
上的属性直接。仅使用
__新__
方法在数据级上进行类似的操作是:1 这还有其他问题: https://github.com/python/cpython/cpython/issues/85281
pathlib.path.path.path.path-path-path-path-like-like 初始评估
您需要包装
__ Init __
功能由@DataClass
添加。您可以使用另一个装饰器进行此操作:
用法:
或者您可以在
__ __新__
中包装__ INT __ INT __
:__init__
is called after__new__
.Creation is essentially:
Therefore, you cannot repack
args
.Also see: Python: override __init__ args in __new__
pathlib.Path-like instantiation
Unlike your dataclass,
pathlib.Path
doesn't have an__init__
method with required parameters.Its
__new__
method calls another class method_from_parts
1 that doesself = object.__new__(cls)
and then sets attributes onself
directly.To do something like this on your dataclass with only the
__new__
method would be:1 This has other issues: https://github.com/python/cpython/issues/85281
pathlib.Path-like initialisation
You need to wrap the
__init__
function added by@dataclass
.You can do this with another decorator:
Usage:
Or you can wrap
__init__
in__new__
: