我正在尝试根据自己的需要扩展属性装饰器,但我不知道如何访问扩展属性中的属性和方法
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中获得了指向“数据”的函数指针。如何从该函数指针中提取类的名称?
答案 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']