抽象属性(不是属性)? [英] Abstract attribute (not property)?

查看:215
本文介绍了抽象属性(不是属性)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

定义抽象实例属性而不将其作为属性的最佳实践是什么?

What's the best practice to define an abstract instance attribute, but not as a property?

我想写一些类似的东西:

I would like to write something like:

class AbstractFoo(metaclass=ABCMeta):

    @property
    @abstractmethod
    def bar(self):
        pass

class Foo(AbstractFoo):

    def __init__(self):
        self.bar = 3

而不是:

class Foo(AbstractFoo):

    def __init__(self):
        self._bar = 3

    @property
    def bar(self):
        return self._bar

    @bar.setter
    def setbar(self, bar):
        self._bar = bar

    @bar.deleter
    def delbar(self):
        del self._bar

属性是方便,但对于不需要计算的简单属性,这是一个过大的杀伤力。这对于将由用户进行子类化和实现的抽象类尤其重要(我不想强迫某人只写了<$时就使用 @property c $ c> self.foo = foo 在 __ init __ 中。)

Properties are handy, but for simple attribute requiring no computation they are an overkill. This is especially important for abstract classes which will be subclassed and implemented by the user (I don't want to force someone to use @property when he just could have written self.foo = foo in the __init__).

<一个href = https://stackoverflow.com/questions/2736255/abstract-attributes-in-python> Python中的抽象属性问题建议使用 @property作为唯一答案 code>和 @abstractmethod :它不能回答我的问题。

Abstract attributes in Python question proposes as only answer to use @property and @abstractmethod: it doesn't answer my question.

通过 AbstractAttribute的抽象类属性 可能是正确的方法,但是我不确定。

The ActiveState recipe for an abstract class attribute via AbstractAttribute may be the right way, but I am not sure. It also only works with class attributes and not instance attributes.

推荐答案

如果您真的想强制子类定义给定的属性,那么它也仅适用于类属性,而不适用于实例属性。 ,您可以使用元类。就我个人而言,我认为这可能是矫kill过正,并且不是很pythonic,但您可以执行以下操作:

If you really want to enforce that a subclass define a given attribute, you can use metaclass. Personally, I think it may be overkill and not very pythonic, but you could do something like this:

 class AbstractFooMeta(type):

     def __call__(cls, *args, **kwargs):
         """Called when you call Foo(*args, **kwargs) """
         obj = type.__call__(cls, *args, **kwargs)
         obj.check_bar()
         return obj


 class AbstractFoo(object):
     __metaclass__ = AbstractFooMeta
     bar = None

     def check_bar(self):
         if self.bar is None:
             raise NotImplementedError('Subclasses must define bar')


 class GoodFoo(AbstractFoo):
     def __init__(self):
         self.bar = 3


 class BadFoo(AbstractFoo):
     def __init__(self):
         pass

元类重新定义 __ call __ 以确保在实例初始化后调用 check_bar

Basically the meta class redefine __call__ to make sure check_bar is called after the init on an instance.

GoodFoo()  # ok
BadFoo ()  # yield NotImplementedError

这篇关于抽象属性(不是属性)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆