Python 使用装饰器验证属性名称
我有一个decorator类Python 使用装饰器验证属性名称,python,properties,decorator,python-decorators,Python,Properties,Decorator,Python Decorators,我有一个decorator类validatekeys()和一个Node3D()类 其目的是让Node3D保存x、y和z的坐标值,这些坐标值是使用@属性装饰器检索的,可以使用@coords.setter装饰器(调用set\u coords())或直接使用本身用validatekeys()装饰的set\u coords()进行设置。我正在使用装饰器来完成这项工作,以便以后可以添加其他类,例如Node2D() 代码: 但是,部分输出不符合预期: n = Node2D() n.coords
validatekeys()
和一个Node3D()
类
其目的是让Node3D
保存x、y和z的坐标值,这些坐标值是使用@属性
装饰器检索的,可以使用@coords.setter
装饰器(调用set\u coords()
)或直接使用本身用validatekeys()装饰的set\u coords()
进行设置
。我正在使用装饰器来完成这项工作,以便以后可以添加其他类,例如Node2D()
代码:
但是,部分输出不符合预期:
n = Node2D()
n.coords #{} <--expected
n.set_coords(x=1,y=2)
n.coords #{} <--not expected
n.set_coords(a=1,b=2) #Exception <--expected
n=Node2D()
n、 coords{}您的调用中的self
指的是验证器,而不是Node3D对象,因此验证器正在更新自己的\u dict\u
。请尝试以下方法:
class validatekeys(object):
def __init__(self,*keysIterable):
self.validkeys = []
for k in keysIterable:
self.validkeys.append(k)
def __call__(validator_self,f):
def wrapped_f(self, *args,**kwargs):
for a in kwargs:
if not a in validator_self.validkeys:
raise Exception()
self.__dict__.update(kwargs)
return f(self, *args, **kwargs)
return wrapped_f
在这里,我将调用中的self
重命名为验证器self
,以明确该self指的是验证器。我在包装器函数中添加了一个self
;此self
将引用已验证方法所在的Node3D对象的“真实”self。您的调用中的self
引用的是验证器,而不是Node3D对象,因此验证器正在更新自己的\udic\ud
。请尝试以下方法:
class validatekeys(object):
def __init__(self,*keysIterable):
self.validkeys = []
for k in keysIterable:
self.validkeys.append(k)
def __call__(validator_self,f):
def wrapped_f(self, *args,**kwargs):
for a in kwargs:
if not a in validator_self.validkeys:
raise Exception()
self.__dict__.update(kwargs)
return f(self, *args, **kwargs)
return wrapped_f
在这里,我将调用中的self
重命名为验证器self
,以明确该self指的是验证器。我在包装器函数中添加了一个self
;此self
将引用已验证方法所在的Node3D对象的“真实”self。您的调用中的self
引用的是验证器,而不是Node3D对象,因此验证器正在更新自己的\udic\ud
。请尝试以下方法:
class validatekeys(object):
def __init__(self,*keysIterable):
self.validkeys = []
for k in keysIterable:
self.validkeys.append(k)
def __call__(validator_self,f):
def wrapped_f(self, *args,**kwargs):
for a in kwargs:
if not a in validator_self.validkeys:
raise Exception()
self.__dict__.update(kwargs)
return f(self, *args, **kwargs)
return wrapped_f
在这里,我将调用中的self
重命名为验证器self
,以明确该self指的是验证器。我在包装器函数中添加了一个self
;此self
将引用已验证方法所在的Node3D对象的“真实”self。您的调用中的self
引用的是验证器,而不是Node3D对象,因此验证器正在更新自己的\udic\ud
。请尝试以下方法:
class validatekeys(object):
def __init__(self,*keysIterable):
self.validkeys = []
for k in keysIterable:
self.validkeys.append(k)
def __call__(validator_self,f):
def wrapped_f(self, *args,**kwargs):
for a in kwargs:
if not a in validator_self.validkeys:
raise Exception()
self.__dict__.update(kwargs)
return f(self, *args, **kwargs)
return wrapped_f
在这里,我将调用中的self
重命名为验证器self
,以明确该self指的是验证器。我在包装器函数中添加了一个self
;此self
将引用已验证方法所在的Node3D对象的“真实”self。您的装饰程序正在更新错误的\u dict\u
<代码>自我
在您的decorator中\uuuu调用\uuuuu
是decorator对象本身
您需要从被调用的包装器中提取绑定的self
参数:
def wrapped_f(*args, **kwargs):
for a in kwargs:
if not a in self.validkeys:
raise Exception()
instance = args[0]
instance.__dict__.update(kwargs)
return f(*args, **kwargs)
您也可以为wrapped\u f()
提供一个显式的第一个参数:
def wrapped_f(instance, *args, **kwargs):
for a in kwargs:
if not a in self.validkeys:
raise Exception()
instance.__dict__.update(kwargs)
return f(instance, *args, **kwargs)
这里实例
绑定到节点3d
实例。注意,没有硬性要求命名这个变量self
;这只是一个惯例。您的装饰程序正在更新错误的\uuu dict\uuu
<代码>自我
在您的decorator中\uuuu调用\uuuuu
是decorator对象本身
您需要从被调用的包装器中提取绑定的self
参数:
def wrapped_f(*args, **kwargs):
for a in kwargs:
if not a in self.validkeys:
raise Exception()
instance = args[0]
instance.__dict__.update(kwargs)
return f(*args, **kwargs)
您也可以为wrapped\u f()
提供一个显式的第一个参数:
def wrapped_f(instance, *args, **kwargs):
for a in kwargs:
if not a in self.validkeys:
raise Exception()
instance.__dict__.update(kwargs)
return f(instance, *args, **kwargs)
这里实例
绑定到节点3d
实例。注意,没有硬性要求命名这个变量self
;这只是一个惯例。您的装饰程序正在更新错误的\uuu dict\uuu
<代码>自我
在您的decorator中\uuuu调用\uuuuu
是decorator对象本身
您需要从被调用的包装器中提取绑定的self
参数:
def wrapped_f(*args, **kwargs):
for a in kwargs:
if not a in self.validkeys:
raise Exception()
instance = args[0]
instance.__dict__.update(kwargs)
return f(*args, **kwargs)
您也可以为wrapped\u f()
提供一个显式的第一个参数:
def wrapped_f(instance, *args, **kwargs):
for a in kwargs:
if not a in self.validkeys:
raise Exception()
instance.__dict__.update(kwargs)
return f(instance, *args, **kwargs)
这里实例
绑定到节点3d
实例。注意,没有硬性要求命名这个变量self
;这只是一个惯例。您的装饰程序正在更新错误的\uuu dict\uuu
<代码>自我
在您的decorator中\uuuu调用\uuuuu
是decorator对象本身
您需要从被调用的包装器中提取绑定的self
参数:
def wrapped_f(*args, **kwargs):
for a in kwargs:
if not a in self.validkeys:
raise Exception()
instance = args[0]
instance.__dict__.update(kwargs)
return f(*args, **kwargs)
您也可以为wrapped\u f()
提供一个显式的第一个参数:
def wrapped_f(instance, *args, **kwargs):
for a in kwargs:
if not a in self.validkeys:
raise Exception()
instance.__dict__.update(kwargs)
return f(instance, *args, **kwargs)
这里实例
绑定到节点3d
实例。注意,没有硬性要求命名这个变量self
;这只是一个约定。如果给wrapped\u f
一个显式的第一个参数,它需要有一个不同于验证器的名称,以避免隐藏它。它需要访问验证器自身才能检索有效密钥列表,该列表存储在验证器上,而不是Node3D对象。@BrenBarn:darn,错过了那里的self.validkeys
。选择此作为正确答案,因为它绝对、肯定、非常清晰。谢谢。如果给wrapped\u f
一个显式的第一个参数,它需要有一个不同于验证器的名称,以避免隐藏它。它需要访问验证器自身才能检索有效密钥列表,该列表存储在验证器上,而不是Node3D对象。@BrenBarn:darn,错过了那里的self.validkeys
。选择此作为正确答案,因为它绝对、肯定、非常清晰。谢谢。如果给wrapped\u f
一个显式的第一个参数,它需要有一个不同于验证器的名称,以避免隐藏它。它需要访问验证器自身,以便检索存储在va上的有效密钥列表