14

タイトルの通りです。

Java im から来て:

private int A;

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

public int getA() {
    return this.A
}

Python でそれを行うには (必要な場合)。また、__setattr__またはの一方__set__がこれに使用される場合、もう一方は何に使用されますか?

編集:明確にする必要があると感じています。Python では、必要になる前にセッターとゲッターを作成しないことを知っています。

次のようなことをしたいとしましょう。

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

これを実装する「Pythonic」の方法は何ですか?

4

4 に答える 4

19

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__(ただし、クラスに複数のプロパティがあるとすぐに面倒になるため、この方法で実装しないでください。この方法で実行すると、プロパティを使用するよりも遅くなると思います):

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__

Pythonには、プライベート変数などはないことに注意してください。一般に、クラスメンバーの前にアンダースコアが付いている場合は、それを台無しにしないでください(もちろん、何をしているのかを理解している場合を除きます)。プレフィックスに2つのアンダースコアが付いている場合、名前マングリングが呼び出され、クラス外へのアクセスが困難になります。これは、継承での名前空間の衝突を防ぐために使用されます(これらの変数も、通常、混乱することはありません)。

于 2012-05-22T17:49:35.427 に答える
8

__set__()記述子がに割り当てられるときに記述子で使用されます。__setattr__()オブジェクトの属性にバインドするときに使用されます。記述子を作成する場合を除いて、を使用することはありません__set__()

于 2012-05-22T17:50:08.253 に答える
8

ゲッター/セッターが本当に些細なものである場合は、気にする必要はありません。インスタンス変数を使用するだけです。何か興味深いことを行う getter/setter が必要な場合は、mgilson が説明したように、プロパティに切り替える必要があります。インスタンス変数からプロパティに変更しても、コードを使用する側は違いに気付かないことに注意してください。つまり、次から始めます。

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

そして、属性を取得/設定するときに何か興味深いことが必要であることが判明した場合にのみ、説明されているプロパティベースのアクセサー mgilson に変更してください。

于 2012-05-22T17:52:06.003 に答える
5

class Masterの属性xを持っていて、 の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
于 2012-05-22T18:16:42.197 に答える