如何在python中的派生属性类中访问方法和属性

时间:2019-01-16 20:14:34

标签: python

我正在尝试根据自己的需要扩展属性装饰器,但我不知道如何访问扩展属性中的属性和方法

class myproperty(property):
    def __init__(self, tooltip, cls_name,
             fget=None, fset=None, fdel=None, doc=None, **kwargs ):
        super().__init__(fget=fget, fset=fset, fdel=fdel, doc=doc)
        self._name = ''
        self._value = ''
        self._cls_name = None        # name of GUI object to be used

        self._datatype = None
        self._tooltip = tooltip
        self._cls_name = cls_name
        self._kwargs = dict(**kwargs)

    def __get__(self, *args, **kwargs):
        return self._datatype(self._value)

    def __set__(self, instance, value):
        self._value = value
        print(f'setting {value}')

    def __call__(self, f):
        self._value = f(self)
        self._datatype= type(self._value )
        self._name = f.__name__
        return self

    def get_membervalues(self):
        return {'name': self._name, 'cls_name': self._cls_name, 'tooltip': self._tooltip}

我可以使用该属性:

class myclass():
    @myproperty(tooltip='help', cls_name='AnotherClass')
    def data(self): return 4

它似乎在内部起作用

a = myclass()
print(a.data)        # prints out 4, __get__() is called
a.data = "10"        #  __set__ is called correctly
print(a.data)        #  prints out 10 correctly
print(type(a.data))  # prints out "int" which is correct
a.get_memvervalues()  # this does not work

如何访问方法“ get_memvervalues”或属性_name,_tooltip等? 香港专业教育学院尝试过检查并将其投放,但尚未成功。 额外的问题:调用def 调用(self,f)函数时,我在myclass中获得了指向“数据”的函数指针。如何从该函数指针中提取类的名称?

2 个答案:

答案 0 :(得分:1)

  

如何访问方法“ get_memvervalues”或属性_name,_tooltip等?

来自班级(myclass):

myclass.__dict__['data']

从类实例(a):

type(a).__dict__['data']

两者中,data是属性名称。

例如:

a = myclass()
desc = type(a).__dict__['data']

print(desc.get_membervalues())    # {
                                  #     'name': 'data', 
                                  #     'cls_name': 'AnotherClass', 
                                  #     'tooltip': 'help'
                                  # }

print(desc._tooltip)              # help

print(vars(desc))                 # {
                                  #     '_name': 'data',
                                  #     '_value': 4,
                                  #     '_cls_name': 'AnotherClass', 
                                  #     '_datatype': <class 'int'>, 
                                  #     '_tooltip': 'help', 
                                  #     '_kwargs': {}
                                  # }

但是,乍一看,您的实现存在问题:

a = myclass()
b = myclass()

print("Before:")        # Before:
print("a:", a.data)     # a: 4
print("b:", b.data)     # b: 4

a.data = 10

print("After:")         # After:
print("a:", a.data)     # a: 10
print("b:", b.data)     # b: 10   (!!!)

如果这对您有意义,那么您可以停止阅读,并且以一种非常规的方式使用方法描述符。

尽管有两个类实例,但只有一个描述符实例:

type(a).__dict__['data'] is type(b).__dict__['data']

(应该显示为type(a) is type(b))。

为了支持描述符“以不同的方式工作”,第一个参数(在instance中称为__set__,但也传递给__get__)是对类实例的引用- -self就是传统方法中的内容。

您通常想以某种方式使用它。

答案 1 :(得分:1)

private static Parser<Expression<Func<string, bool>>> Lambda => AndTerm.End().Select(body => Expression.Lambda<Func<string, bool>>(body, Param)); 未在get_membervalues内定义,因此myclass将无权访问。

它是在a内部定义的,因此下一个逻辑结论是尝试到达与myproperty关联的myproperty对象。由于Python将函数存储在a.data中的myclass中,因此我们可以像这样找到属性对象:

myclass.__dict__

然后从那里调用函数:

a.__class__.__dict__['data']