Python 使用函数编写不同的类属性

Python 使用函数编写不同的类属性,python,attributes,Python,Attributes,我想创建一个函数来写入Python类中的属性,但是能够决定是否应该写入该属性 class Test(object): def __init__(self): self.a = None self.b = None def write_attrib(self,which_attrib,value): # perform a check here which_attrib = value def write_

我想创建一个函数来写入Python类中的属性,但是能够决定是否应该写入该属性

class Test(object):
    def __init__(self):
        self.a = None
        self.b = None

    def write_attrib(self,which_attrib,value):
        # perform a check here
        which_attrib = value

    def write_a(self,value):
        self.write_attrib(self.a, value)

    def write_b(self,value):
        self.write_attrib(self.b, value)

if __name__ == '__main__':
    t  = Test()
    t.write_a(5)
    t.write_b(4)
    print(t.a, t.b)
现在,这将导致两个值均为
None
,因此函数未触及它们


我希望使用这种方法,这样我可以在写入属性之前在
write\u attrib
中进行一些检查,并且我不必写两次这些检查(但希望使方便的函数
write\u a
write\u b
可用)。

使用
属性

class Test(object):
    def __init__(self):
        self._a = None

    @property:
    def a(self):
        return self._a

    @a.setter
    def a(self, value):
        # Do your validation here
        self._a = value

使用
属性

class Test(object):
    def __init__(self):
        self._a = None

    @property:
    def a(self):
        return self._a

    @a.setter
    def a(self, value):
        # Do your validation here
        self._a = value

要基于我的评论,您可以实现
\uuuu setattr\uuuu
以仅验证您指定的属性:

class Test(object):

    VALIDATED = {'a', 'b'}

    def __init__(self):
        self.a = None
        self.b = None

    def __setattr__(self, attr, val):
        if attr in self.VALIDATED:
            pass  # add your checking
        super(Test, self).__setattr__(attr, val)
或者,您可以为要验证的属性实现一个
@属性
,管理对私有按约定属性的访问(标识符中有一个前导下划线):


如果有许多属性具有相同的验证规则,则前者可能更整洁;如果每个属性具有较少的属性和/或不同的验证规则,则后者可能更整洁。这两种方法都允许您拥有干净的属性访问权限,而无需getter或setter(参见示例)。

要基于我的评论,您可以实现
\uuuuuu setattr\uuuu
来仅验证您指定的属性:

class Test(object):

    VALIDATED = {'a', 'b'}

    def __init__(self):
        self.a = None
        self.b = None

    def __setattr__(self, attr, val):
        if attr in self.VALIDATED:
            pass  # add your checking
        super(Test, self).__setattr__(attr, val)
或者,您可以为要验证的属性实现一个
@属性
,管理对私有按约定属性的访问(标识符中有一个前导下划线):


如果有许多属性具有相同的验证规则,则前者可能更整洁;如果每个属性具有较少的属性和/或不同的验证规则,则后者可能更整洁。两者都允许您拥有干净的属性访问,而不需要getter或setter(参见示例)。

为什么要这样做?为什么不在
write\u attrib
中使用例如
setattr(t,'a',5)
(或
setattr(self,which attrib,value)
),或者如果在设置特定属性时需要执行某些特定操作,则可以实现
@property
甚至
\uu setattr
?你到底想实现什么?也许我只是不知道神奇的方法setattr,但在编写属性之前,我想做一些错误检查以确保一致性。如果我更改setattr,这将适用于所有属性(我不希望这样),但我可以使用@property仅对某些属性执行此操作?这是如何工作的?您可以实现
\uuuu setattr\uuuu
以仅对指定属性列表应用检查,而忽略其余属性。如果要实现属性,请阅读,例如,为什么要这样做?为什么不在
write\u attrib
中使用例如
setattr(t,'a',5)
(或
setattr(self,which attrib,value)
),或者如果在设置特定属性时需要执行某些特定操作,则可以实现
@property
甚至
\uu setattr
?你到底想实现什么?也许我只是不知道神奇的方法setattr,但在编写属性之前,我想做一些错误检查以确保一致性。如果我更改setattr,这将适用于所有属性(我不希望这样),但我可以使用@property仅对某些属性执行此操作?这是如何工作的?您可以实现
\uuuu setattr\uuuu
以仅对指定属性列表应用检查,而忽略其余属性。如果要实现属性,请阅读,例如,请注意在
\uuuu init\uuuu
中指定给
self.a
而不是
self.\u a
意味着验证也在那里运行,这通常是一种良好的做法。如果以后为常规属性引入属性,它还可以最大限度地减少代码更改。请注意,在
\uuu init\uuu
中指定给
self.a
而不是
self.\u a
意味着验证也在那里运行,这通常是一种良好的做法。如果以后为常规属性引入属性,它还可以最大限度地减少代码更改。
self.a
中的
a
实际上是对在实例化
Test
时设置
self.\u a=None
的属性的引用。是这样吗?@xyres是的:
self.a=None
调用
self.a.setter(None)
设置
self.\u a=None
。谢谢。这真的很有创意,没问题。例如,如果
None
是有效的起始值,但不是您希望用户设置的值,则可以直接将a分配给私有属性。如果您对此感兴趣,我昨天回答了一个类似的问题:
self中的
a
。a
实际上是在实例化
Test
时对设置
self.\u a=None
的属性的引用。是这样吗?@xyres是的:
self.a=None
调用
self.a.setter(None)
设置
self.\u a=None
。谢谢。这真的很有创意,没问题。例如,如果
None
是有效的起始值,但不是您希望用户设置的值,则可以直接将a分配给私有属性。如果你对此感兴趣,我昨天回答了一个类似的问题: