python - 通过子类化 `type` 类来实现类描述符

标签 python class properties class-attributes descriptor

我希望有一些数据描述符作为类的一部分。这意味着我希望类属性实际上是属性,其访问由类方法处理。

Python似乎并不直接支持这一点,但是可以通过子类化type类来实现。因此,向 type 的子类添加属性将导致其实例具有该属性的描述符。它的实例是类。因此,类描述符。

这是可取的吗?有什么我应该注意的问题吗?

最佳答案

约定(通常),当在类上访问描述符时,返回描述符对象本身。这就是property的作用;如果您访问类上的属性对象,则会返回该属性对象(因为这是它的 __get__ 方法选择执行的操作)。但这是惯例。您不必这样做。

因此,如果您只需要在类上有一个 getter 描述符,并且您不介意尝试设置会覆盖该描述符,那么您可以执行类似的操作,而无需元类编程:

def classproperty_getter_only(f):
    class NonDataDescriptor(object):
        def __get__(self, instance, icls):
            return f(icls)
    return NonDataDescriptor()

class Foo(object):

    @classproperty_getter_only
    def flup(cls):
        return 'hello from', cls

print Foo.flup
print Foo().flup

对于

('hello from', <class '__main__.Foo'>)
('hello from', <class '__main__.Foo'>)

如果您想要一个完整的数据描述符,或者想要使用内置的属性对象,那么您是对的,您可以使用元类并将其放在那里(意识到该属性对于您的实例来说是完全不可见的)类;在类的实例上进行属性查找时不会检查元类)。

是否值得推荐?我不这么认为。我不会在生产代码中做你随意描述的事情;只有当我有一个非常令人信服的理由时,我才会考虑这样做(而且我无法立即想到这种情况)。元类非常强大,但并非所有程序员都能很好地理解它们,并且有些难以推理,因此它们的使用使您的代码更难以维护。我认为这种设计会受到整个 Python 社区的反对。

关于python - 通过子类化 `type` 类来实现类描述符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3277047/

相关文章:

python - NoneType对象没有属性 'play'

python - 代码中的ipython笔记本清除单元格输出

php - PHP 单例类的最佳实践

properties - Swift 属性覆盖不起作用

python - 尽管安装了开发包,但找不到 tk.h

java - 带有方法 toString() 的新类

扩展类中的PHP依赖注入(inject)

objective-c - 在 Objective-C 中,重写合成 setter 的正确方法是什么?

objective-c - objective-c 中的@property 和@synthesize

python - 在 Django 选择表单的模型选择字段中列出各种模型属性