【问题标题】:Check the owner type in `__set_name__` method introduced in python 3.6+ PEP-0487在 python 3.6+ PEP-0487 中引入的 `__set_name__` 方法中检查所有者类型
【发布时间】:2019-10-11 17:36:39
【问题描述】:

我想检查所有者类类型并允许Field 类属性与Dataset 类或其任何子类一起使用。那就是我希望其他开发人员不要意外地将Field 类与不是Dataset 子类的任何其他类一起使用。

Dataset 似乎还没有完全加载。

print(f"Field: {name!r} of {owner!r} ...") 确实表明所有者类是Dataset

但是代码在下一条语句 if issubclass(owner, Dataset): 处失败,因为 python 仍然不知道类 Dataset


class Field:
    def __set_name__(self, owner, name):
        print(f"Field: {name!r} of {owner!r} ...")
        self.name = name
        if issubclass(owner, Dataset):
            raise Exception(
                f"Use the class {Field!r} only with class {Dataset!r}...."
            )

class Dataset:
    field = Field()

预计运行不会引发任何错误。但相反,我得到了

Field: 'field' of <class '__main__.Dataset'>...

NameError: name 'Dataset' is not defined

【问题讨论】:

  • 每个字符串之前的f 是什么(去掉它会消除错误)。
  • @goodvibration 这是一个名为f-strings 的新功能,从 python 3.6+ 引入。如果使用旧版本,可能会出现编译错误。但是这段代码会抛出错误,因为Dataset 尚未完全加载。
  • 我不完全确定您是否想限制FieldDataset 之外使用。 Python 是鸭子类型的,你永远不知道其他人会想出什么。

标签: python-3.x python-3.6


【解决方案1】:

发生这种情况是因为我们仍处于构建Database 类的过程中,而且它还不能在全局范围内使用。我希望有人提出更好的解决方案,但一种解决方法是增加一个不执行任何操作的基类:

class _DatasetBase:
    pass

class Field:
    def __set_name__(self, owner, name):
        print(f"Field: {name!r} of {owner!r} ...")
        self.name = name
        if not issubclass(owner, _DatasetBase):
            raise Exception(
                f"Use the class {Field!r} only with class {Dataset!r}...."
            )

class Dataset(_DatasetBase):
    field = Field()

【讨论】:

    猜你喜欢
    • 2019-04-13
    • 2016-08-03
    • 2022-01-21
    • 2013-12-18
    • 1970-01-01
    • 2019-03-21
    • 2018-02-08
    • 2010-09-14
    • 1970-01-01
    相关资源
    最近更新 更多