繁体   English   中英

为什么在python中使用__setattr__?

[英]Why to use __setattr__ in python?

我不知道为什么使用__setattr__而不是简单的引用,如xa=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)

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

你能解释一下__setattr__优点是__setattr__吗?

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

然而,它是为你而调用的 - 当你做ax = ... ,这a.__setattr__('x', ...) (这可能是过于简单化)。 并且一些对象超载它以允许一些欺骗,例如模仿不变性。 请参阅“特殊方法”的文档。

__setattr__是由setattr builtin方法调用的类方法。 也就是说,如果在给定的类中定义了__setattr__ 大多数情况下,你没有声明自己的__setattr__版本,所以我假设你问的是setattr方法有什么用处。

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

class A(object):
    def doSth(self, name, val):
        setattr(self, name, val)

self.name = val

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

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

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

请注意, __xxx__是类的运算符重载方法,因此只应在特殊情况下使用,而不是在示例中使用。

例如, __setattr__拦截所有属性赋值,并且可以在将值分配给属性时用于更改类的行为。

__setattr__的第一次使用是在类定义中被覆盖。

class Foo ( object ) :

    def __init__ ( self ) :
        self.x = 'looser'

    def __setattr__ ( self, name, value ) :
        if name == 'x' :
            print( 'Hello, {} !'.format( value ) )
            self.x = value

问题, Foo()将打印无限序列:

'Hello, looser !'

第二种用法是,当你这样做时,你可以从父类(默认情况下是object )调用setattr来避免infite递归:

class Foo ( object ) :

    def __setattr__ ( self, name, value ) :
        self.bar( name, value )
        object.__setattr__( self, name, value )

    def bar ( self, name, value ) :
        print( 'Setting {} to {}.'.format( name, value ) )

因此:

f = Foo()

>> 'Hello, winner !'

f.x

>> 'winner'

__setattr__可以用于反射,其中可以在运行时创建对象Rectangle的属性,在http://en.wikipedia.org/wiki/Reflection_%28computer_science%29上有更多关于它的内容。

class Rectangle:
    def __init__(self):
        #... code ...

x = Rectangle()
#x.__setattr__('newProperty',30)      Edited after comment
setattr(x, 'newProperty', 30)
print x.newProperty #>>> 30
class Name(object):
    pass

obj=Name()

#just i have created object two way 
#first

obj.a="first"
print obj.a

#answer= "first"
#second

obj.__setattr__('b','second')
print obj.a
#answer= "second"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM