为什么在python中使用__setattr__?

use*_*618 23 python setter

我不知道为什么使用__setattr__简单的引用之类的x.a=1.

我理解这个例子:

class Rectangle:
    def __init__(self):
        self.width = 0
        self.height = 0


x=Rectangle()
x.width=20
x.__setattr__('height',30)
setattr(x,'width',99)
Run Code Online (Sandbox Code Playgroud)

但不明白为什么使用代码取决于字符串('高度').

你能解释一下我有什么好处__setattr__吗?

小智 30

你不要自己打电话.期.如果你需要使用一个字符串,因为你事先不知道这个名字(非常糟糕的想法在99%的情况下,人们可能认为他们需要这个,几乎总是一个字典或列表是一个更好/更健全的选择),你使用内置setattr功能.

然而,它被称为你 - 当你这样做时a.x = ...,那就完成了a.__setattr__('x', ...)(这可能是过于简单化).并且一些对象超载它以允许一些欺骗,例如模仿不变性.请参阅"特殊方法"的文档.


paj*_*ton 15

__setattr__是一个由setattrbuiltin方法调用的类方法.也就是说,如果__setattr__在给定的类中定义.大多数情况下你没有声明你自己的版本,__setattr__所以我假设你问的是该setattr方法的用途.

假设您有一个var,其中包含您要设置的属性的名称,而不仅仅是知道名称:

class A(object):
    def doSth(self, name, val):
        setattr(self, name, val)
Run Code Online (Sandbox Code Playgroud)

不可能 self.name = val

此外,常见的用法是使用关键字args:

class A(object):
    def __init__(self, *args, **kwargs):
        for k,v in kwargs.items():
            setattr(self, k, v)
Run Code Online (Sandbox Code Playgroud)

  • 是的,它确实.如果定义,使用`setattr`会通过自定义`__setattr__`.请注意,自定义`__setattr__`根本不需要触及`__dict__`(对于某些动态属性查找,代理等,使用`__setattr__`是很常见的). (5认同)
  • 后者构造是否比"self .__ dict __.update(kwargs)"有任何进步? (3认同)

Pet*_*ley 7

我可以设想一个应用程序,例如,您覆盖__setattr____getattr__提供对未保存在内存中的其他数据结构的类似对象的访问.例如,您可以创建一个对象,其中foo.CustomerName = "John"更新CustomerName指向的数据库行中的列foo以包含该值"John".即,foo.__setattr__将使用属性名称和值来构造更新磁盘上的数据库的命令.我不想写这样的东西,但这是可能的.

  • 这正是我过去使用过`__setattr__`的原因.这不是为了佯攻,我建议任何需要这种特殊功能的人进行严格的测试(甚至是"测试驱动开发"). (2认同)