簡體   English   中英

Python中的__set__和__setattr__有什么區別?何時使用?

[英]What is the difference between __set__ and __setattr__ in Python and when should which be used?

如標題所示。

來自Java,即時通訊用於:

private int A;

public void setA(int A) {
    this.A = A;
}

public int getA() {
    return this.A
}

如何在Python中執行此操作(如果需要)。 如果__set__使用__setattr____set__一個,則另一個用於什么呢?

編輯:我覺得我需要澄清。 我知道在Python中,doe不需要先創建setter和getter。

可以說我想做這樣的事情:

public void setA(int A) {
    update_stuff(A);
    and_calculate_some_thing(A);
    this.A = A;
}

實現此目的的“ pythonic”方法是什么?

在python中, 應該使用property來實現類似的操作(只有當它們做一些有用的事情時才可以)。

class Foo(object):
    def __init__(self):
        self._x = None

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self,y):
        self._x = y

在此示例中,最好做一下(如愛德華指出的那樣):

class Foo(object):
     def __init__(self):
         self.x = None

因為我們的getter / setter方法實際上不做任何事情...但是,當setter / getter實際上要做的不僅僅是分配/返回屬性值時,屬性變得非常有用。

也可以使用__setattr__ / __getattr__來實現(但不應以這種方式實現,因為如果您的類具有多個屬性,它將很快變得麻煩。我還猜想,以這種方式進行操作會比使用屬性來得慢):

class Foo(object):
    def __init__(self):
        self._x = None
    def __setattr__(self,attr,obj):
        if(attr == 'x'):
            object.__setattr__(self,'_x',obj)
        else:
            object.__setattr__(self,attr,obj)

    def __getattr__(self,attr):
        if(attr == 'x'):
            return object.__getattr__(self,'_x')
        else:
            return object.__getattr__(self,attr)

__setattr____getattr__實際作用__setattr____getattr__ __setattr__ / __getattr__是執行以下操作時所要調用的:

myclassinstance = MyClass()
myclassinstance.x = 'foo'  #translates to MyClass.__setattr__(myclassinstance,'x','foo')
bar = myclassinstance.x    #translates to bar=MyClass.__getattr__(myclassinstance,'x')

至於__get____set__以前的帖子 __set__進行了很好的討論。

請注意,在python 中沒有私有變量之類的東西 通常,在類成員中以下划線作為前綴,您不應該將其弄亂(除非您當然知道自己在做什么)。 如果以2個下划線作為前綴,它將調用名稱修改,這使得在類外部進行訪問變得更加困難。 這用於防止繼承中的名稱空間沖突(通常也不要弄混那些變量)。

如果getter / setter確實如此瑣碎,那么您甚至不必理會它們:只需使用實例變量即可。 如果您確實需要做一些有趣的getter / setter,那么您應該切換到屬性,如mgilson所述。 請注意,您可以從實例變量更改為屬性,而無需任何使用您的代碼的方法來注意差異。 即,開始於:

class Foo(object):
    def __init__(self):
        self.x = None

並且僅更改為基於屬性的訪問器,如果/當事實證明您需要獲取/設置屬性時需要發生一些有趣的事情,mgilson會對此進行描述。

分配描述符時,在描述符中使用__set__() 綁定到對象的屬性時使用__setattr__() 除非創建描述符,否則將不會使用__set__()

假設您擁有一個具有屬性x class Master ,該屬性屬於class Slave並且您希望在將某物分配給x時執行某些代碼,例如some_master.x = foo 該代碼位於何處? 它可以在Master類中,在這種情況下,您可以使用__setattr__ 它也可以在Slave類中,以便可以控制要分配的內容。 在這種情況下,您可以使Slave成為描述符,並使用__set__

例子:

>>> class Master(object):
...     def __setattr__(self, name, val):
...         print "run code in Master: %s" % val
... 
>>> a = Master()
>>> a.x = 123
run code in Master: 123

與此相比:

>>> class Slave(object):
...     def __set__(self, obj, val):
...         print "run code in Slave: %s" % val
... 
>>> class Master2(object):
...     x = Slave()
... 
>>> b = Master2()
>>> b.x = 345
run code in Slave: 345

要回答哪個是更pythonic的問題,我都不會說。 如果您需要實際執行某項操作,請將其設為功能。 顯式>隱式。

 def update_param(a):
     update_stuff(a)
     and_calculate_some_thing(a)
     self.a = a

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM