我正在使用描述符(文档 here ),因此每个值都会自动转换为 float 。
from dataclasses import dataclass
class ToFloat:
def __set_name__(self, owner, name):
self.public_name = name
self.private_name = '_' + name
def __get__(self, obj, objtype=None):
value = getattr(obj, self.private_name)
return value
def __set__(self, obj, value):
setattr(obj, self.private_name, float(value))
@dataclass
class Coordinates:
lon: float = ToFloat()
lat: float = ToFloat()
val: float = ToFloat()
c = Coordinates(lon=1 , lat=2, val=3)
# 1.0 2.0 3.0
但是,如何使这些字段成为可选字段? (有或没有@dataclass
)。
这不起作用:
c = Coordinates()
# TypeError: __init__() missing 3 required positional arguments: lat, long, val
最佳答案
这是一个似乎有效的简单直接的解决方案。我正在使用 PyCharm,当我将字段名称遗漏给 __init__
方法时,它似乎没有显示任何类型警告等。
from dataclasses import dataclass, field
class ToFloat:
def __init__(self, default_value=None):
self.default = default_value
def __set_name__(self, owner, name):
self.public_name = name
self.private_name = '_' + name
def __get__(self, obj, objtype=None):
value = getattr(obj, self.private_name)
return value
def __set__(self, obj, value):
if isinstance(value, ToFloat):
setattr(obj, self.private_name, self.default)
else:
setattr(obj, self.private_name, float(value))
@dataclass
class Coordinates:
lon: float = field(default=ToFloat(0.0))
lat: float = field(default=ToFloat(0.1))
val: float = field(default=ToFloat(0.2))
c = Coordinates(lon=1, lat=2, val=3)
print(c)
# Coordinates(lon=1.0, lat=2.0, val=3.0)
c = Coordinates()
print(c)
# Coordinates(lon=0.0, lat=0.1, val=0.2)
如果您想简化 __set__
下的逻辑(现在每次都会进行 isinstance
检查),您可以简单地这样使用:
def __set__(self, obj, value):
setattr(obj, self.private_name, float(value))
def __float__(self):
return self.default
关于python - 可选参数和描述符实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68984699/