Python 元类 - 通过类和类实例访问类属性 [英] Python metaclass - make class property accessible via class and class instance

查看:41
本文介绍了Python 元类 - 通过类和类实例访问类属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 python 3.7,我在元类中创建了一个类属性.我希望能够通过类本身或类的实例化对象访问该属性.我可以通过创建一个类属性和一个实例属性来模拟它,但它与 PyCharm 的类型提示有问题.以下是我认为的理想设置:

类元(类型):@财产def cls_prop(cls) ->字符串:返回 '​​foo'A类(元类=元):经过

但不幸的是,结果如下:

<预><代码>>>>a.cls_prop'富'>>>a = A()>>>a.cls_prop回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中AttributeError: 'A' 对象没有属性 'cls_prop'

A 添加一个实例属性,调用类属性在运行时有效,但 PyCharm 的类型自省变得混乱(它开始将 A.cls_prop 视为 >property 而不是 str):

A 类(元类=元):@财产def cls_prop(self) ->字符串:返回 self.__class__.cls_prop>>>a.cls_prop'富'>>>a = A()>>>a.cls_prop'富'

有没有更好的方法来做到这一点?

解决方案

我认为使用父类可以更好地完成您正在尝试做的事情:

class 父类:@财产def cls_prop(self):返回 '​​foo'A类(父母):经过>>>a = A()>>>a.cls_prop'富'>>>>a.cls_prop<0x7f1afcb190e8 处的属性对象>

如果您还希望能够直接在类上访问 A.cls_prop(即不创建实例),您可能需要查看另一个问题:@staticmethod 和@property

Using python 3.7, I have created a class property in a metaclass. I would like to be able to access the property via the class itself or an instantiated object of the class. I can emulate it by creating a class property AND an instance property, but it screws with PyCharm's type hinting. Here's what I consider the ideal set up:

class Meta(type):
    @property
    def cls_prop(cls) -> str:
        return 'foo'


class A(metaclass=Meta):
    pass

But unfortunately, here are the results:

>>> A.cls_prop
'foo'
>>> a = A()
>>> a.cls_prop
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'cls_prop'

Adding an instance property to A that calls to the class property works at runtime, but PyCharm's type introspection gets confused (it starts treating A.cls_prop as a property instead of a str):

class A(metaclass=Meta):
  @property
  def cls_prop(self) -> str:
      return self.__class__.cls_prop

>>> A.cls_prop
'foo'
>>> a = A()
>>> a.cls_prop
'foo'

Is there a better way to do this?

解决方案

I think what you are trying to do is better accomplished using a parent class:

class Parent:
    @property
    def cls_prop(self):
        return 'foo'

class A(Parent):
    pass

>>> a = A()
>>> a.cls_prop
'foo'
>>>> A.cls_prop
<property object at 0x7f1afcb190e8>

If you also want to be able to access A.cls_prop directly on the class (i.e. without creating an instance), you might want to look at this other question: @staticmethod with @property

这篇关于Python 元类 - 通过类和类实例访问类属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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