正如标题所说。
来自Java im以前:
private int A;
public void setA(int A) {
this.A = A;
}
public int getA() {
return this.A
}
如何在Python中执行此操作(如果需要)。
如果__setattr__
或__set__
中的一个用于此目的,那么另一个用于什么?
编辑: 我觉得我需要澄清一下。我知道在Python中,一个doe不会在需要之前创建setter和getter。
让我们说我想做这样的事情:
public void setA(int A) {
update_stuff(A);
and_calculate_some_thing(A);
this.A = A;
}
实现此目的的“pythonic”方式是什么?
答案 0 :(得分:14)
在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
在这个例子中,最好这样做(正如Edward所指出的那样):
class Foo(object):
def __init__(self):
self.x = None
因为我们的getter / setter方法实际上并没有做任何事情......但是,当setter / getter实际上做的不仅仅是分配/返回属性的值时,属性变得非常有用。
它也可以使用__setattr__
/ __getattr__
来实现(但它不应该以这种方式实现,因为如果你的类有超过1个属性,它会很快变得很麻烦。我也会猜测这样做会比使用属性慢:
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__
就会被调用:
myclassinstance = MyClass()
myclassinstance.x = 'foo' #translates to MyClass.__setattr__(myclassinstance,'x','foo')
bar = myclassinstance.x #translates to bar=MyClass.__getattr__(myclassinstance,'x')
至于__get__
和__set__
:previous posts已经很好地讨论了这个问题。
请注意,在python 中没有私有变量这样的东西。一般来说,在一个班级成员的前缀下加一个下划线,你不应该惹它(除非你知道你当然在做什么)。如果它以2个下划线为前缀,它将调用名称修改,这使得在类外部访问更加困难。这用于防止继承中的命名空间冲突(这些变量通常也不会被搞乱)。
答案 1 :(得分:8)
如果getter / setter真的那么简单,那么你甚至不应该为它们烦恼:只使用一个实例变量。如果你确实需要一个有趣的getter / setter,那么你应该切换到一个属性,就像mgilson所描述的那样。请注意,您可以从实例变量更改为属性,而无需使用代码注意差异的任何内容。即,从:
开始class Foo(object):
def __init__(self):
self.x = None
只有改变基于属性的访问者mgilson描述了当你得到/设置属性时,你需要发生一些有趣的事情。
答案 2 :(得分:7)
__set__()
用于描述符。绑定到对象的属性时使用__setattr__()
。除非您正在创建描述符,否则不会使用__set__()
。
答案 3 :(得分:4)
假设您class Master
的属性x
为class Slave
,并且您希望在向x
分配内容时执行一些代码,如同{ {1}}。这段代码在哪里?它可以在班级some_master.x = foo
中,在这种情况下,您使用Master
。它也可以在类__setattr__
中,以便它可以控制所分配的内容。在这种情况下,您将Slave
设为descriptor并使用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
要回答哪一个更pythonic,我不会说。如果您需要实际执行某事,请将其作为一项功能。明确的>隐式的。
>>> 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