web-dev-qa-db-ja.com

Pythonでクラスのメンバー変数にアクセスしますか?

class Example(object):
    def the_example(self):
        itsProblem = "problem"

theExample = Example()
print(theExample.itsProblem)

クラスの変数にアクセスするにはどうすればよいですか?私はこの定義を追加しようとしました:

def return_itsProblem(self):
    return itsProblem

しかし、それも失敗します。

65
Adam

数語での答え

あなたの例では、itsProblemはローカル変数です。

インスタンス変数を設定および取得するには、selfを使用する必要があります。 __init__メソッドで設定できます。あなたのコードは次のようになります:

class Example(object):
    def __init__(self):
        self.itsProblem = "problem"


theExample = Example()
print(theExample.itsProblem)

ただし、真のクラス変数が必要な場合は、クラス名を直接使用します。

class Example(object):
    itsProblem = "problem"


theExample = Example()
print(theExample.itsProblem)
print (Example.itsProblem)

ただし、theExample.itsProblemExample.itsProblemと等しくなるように自動的に設定されますが、まったく同じ変数ではなく、個別に変更できるため、これには注意してください。

説明

Pythonでは、変数を動的に作成できます。したがって、次のことができます。

class Example(object):
    pass

Example.itsProblem = "problem"

e = Example()
e.itsSecondProblem = "problem"

print Example.itsProblem == e.itsSecondProblem 

プリント

本当だ

したがって、これはまさに前の例で行うことです。

実際、Pythonでは、selfthisとして使用しますが、それ以上です。最初の引数は常にオブジェクト参照であるため、selfはオブジェクトメソッドの最初の引数です。これは、selfと呼ぶかどうかにかかわらず、自動的に行われます。

それはあなたができることを意味します:

class Example(object):
    def __init__(self):
        self.itsProblem = "problem"


theExample = Example()
print(theExample.itsProblem)

または:

class Example(object):
    def __init__(my_super_self):
        my_super_self.itsProblem = "problem"


theExample = Example()
print(theExample.itsProblem)

まったく同じです。 ANYオブジェクトメソッドの最初の引数は現在のオブジェクトです。慣例としてselfとだけ呼んでいます。そして、このオブジェクトは、外部から行うのと同じ方法です。

今、クラス変数について

行うとき:

class Example(object):
    itsProblem = "problem"


theExample = Example()
print(theExample.itsProblem)

最初にクラス変数を設定に気づき、次にオブジェクト(インスタンス)変数にアクセスします。このオブジェクト変数を設定することはありませんが、機能します。どのように可能ですか?

さて、Pythonは最初にオブジェクト変数を取得しようとしますが、見つからない場合はクラス変数を取得します。 警告:クラス変数はインスタンス間で共有され、オブジェクト変数は共有されません。

結論として、オブジェクト変数にデフォルト値を設定するためにクラス変数を使用しないでください。そのために__init__を使用します。

最終的に、Pythonクラスはインスタンスであり、したがってオブジェクト自体であることがわかります。これにより、上記の理解に新しい洞察が得られます。戻ってきて、後で気づいたらもう一度読んでください。

117
e-satis

クラス変数ではなく、ローカル変数を宣言しています。インスタンス変数(属性)を設定するには、使用します

class Example(object):
    def the_example(self):
        self.itsProblem = "problem"  # <-- remember the 'self.'

theExample = Example()
theExample.the_example()
print(theExample.itsProblem)

クラス変数 (別名静的メンバー)を設定するには、使用します

class Example(object):
    def the_example(self):
        Example.itsProblem = "problem"
        # or, type(self).itsProblem = "problem"
        # depending what you want to do when the class is derived.
10
kennytm

インスタンス関数(つまり、selfが渡される関数)がある場合、selfを使用して、self.__class__を使用してクラスへの参照を取得できます。

たとえば、以下のコードでは、tornadoがgetリクエストを処理するインスタンスを作成しますが、get_handlerクラスを取得し、それを使用してriakクライアントを保持できるため、リクエストごとにインスタンスを作成する必要はありません。

import tornado.web
import riak

class get_handler(tornado.web.requestHandler):
    riak_client = None

def post(self):
    cls = self.__class__
    if cls.riak_client is None:
        cls.riak_client = riak.RiakClient(pb_port=8087, protocol='pbc')
    # Additional code to send response to the request ...
1
andrew pate