python - 可选参数和描述符实例

标签 python python-dataclasses python-descriptors

我正在使用描述符(文档 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/

相关文章:

python - 迭代数据帧时所做的更改不会保存

python - 无效的实例 ID : An error occurred (InvalidInstanceId) when calling the SendCommand operation

python - 为什么人们在 __get__ 中将 owner 参数默认为 None?

python - 如何临时赋值成员变量?

python - 在类和实例上表现不同的函数

python - 如何在 python 中使用 If else 条件来检查文件是否存在?

python - 在 Linux 上通过 Python 脚本截取屏幕截图

python - 新的注释打破了对数据类的检查

python卡住数据类不可变对象(immutable对象).__setattr__

python - 为什么 Python 3.7 数据类不支持 < > <= 和 >=,或者它们支持?