如何在类定义中设置属性

Posted

技术标签:

【中文标题】如何在类定义中设置属性【英文标题】: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。

【问题讨论】:

attr = 'attr' 不创建属性。 也许考虑只创建一个抽象方法attr.getter abc.abstractmethod + property的可能重复 【参考方案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

【讨论】:

以上是关于如何在类定义中设置属性的主要内容,如果未能解决你的问题,请参考以下文章

如何在自定义 HttpMessageHandler 中设置属性?

如何在 django 表单中设置自定义 HTML 属性?

如何从视图控制器的 uitextfield 在类中设置 NSString

如何从 java api 在 keycloak 中设置自定义用户属性

如何在类外设置结构值?

如何在 FolderBrowserDialog 中设置只读属性