[英]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.