Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用装饰器验证属性名称_Python_Properties_Decorator_Python Decorators - Fatal编程技术网

Python 使用装饰器验证属性名称

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

我有一个decorator类
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上的有效密钥列表