【问题标题】:How to impose to set a property in class definition如何在类定义中设置属性
【发布时间】:2018-08-13 14:07:43
【问题描述】:

我想创建一个抽象类,如果子类没有实现抽象属性,子类在实例化时会引发错误。如果属性是方法而不是属性,也应该引发错误。我的尝试:

from abc import ABC, abstractmethod
class IClass(ABC):
    @property
    @abstractmethod
    def attr(self):
        pass

不幸的是,这并不能阻止使用attr 方法而不是属性来实例化子类。

该解决方案应产生以下结果:

class C(IClass):
    pass
C()  # Must fail because 'attr' has not been implemented

class C(IClass):
    def attr(self):
        pass
C().attr  # Must fail because attribute 'attr' is a method rather than a property

class C(IClass):
    attr = 'attr'
C().attr  # Must pass because 'attr' is a property

手册:docs

【问题讨论】:

标签: python python-3.x abstract-class abc


【解决方案1】:

这不如装饰器方便,但您可以验证该属性是__new__ 中的属性,例如:

代码:

from abc import ABC, abstractmethod

class IClass(ABC):
    def __new__(cls, *args, **kwargs):
        new = super().__new__(cls, *args, **kwargs)
        if not isinstance(type(new).attr, property):
            raise TypeError('attr must be a property')
        return new

    @property
    @abstractmethod
    def attr(self):
        pass

测试代码:

class A(IClass):
    pass
try:
    # Must fail because 'attr' has not been implemented
    A()
except Exception as exc:
    print('A Passed: {}'.format(exc))

class B(IClass):
    def attr(self):
        pass
try:
    # Must fail because attribute 'attr' is a method rather than a property
    B()
except Exception as exc:
    print('B Passed: {}'.format(exc))

class C(IClass):
    @property
    def attr(self):
        return 'Good'

# Must pass because 'attr' is a property
print('C Passed: {}'.format(C().attr))

结果:

A Passed: Can't instantiate abstract class A with abstract methods attr
B Passed: attr must be a property
C Passed: Good

【讨论】:

    猜你喜欢
    • 2021-07-21
    • 1970-01-01
    • 2021-07-08
    • 2013-09-04
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多