Доступ к переменным-членам класса в Python?

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

theExample = Example()
print(theExample.itsProblem)

Как получить доступ к переменной класса? Я попытался добавить это определение:

def return_itsProblem(self):
    return itsProblem

Тем не менее, это также не удается.

Ответ 1

Ответ, в нескольких словах

В вашем примере его 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.itsProblem автоматически устанавливается равным Example.itsProblem, но не является той же самой переменной вообще и может быть изменена независимо.

Некоторые объяснения

В Python переменные могут создаваться динамически. Поэтому вы можете сделать следующее:

class Example(object):
    pass

Example.itsProblem = "problem"

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

print Example.itsProblem == e.itsSecondProblem 

печать

Правда

Поэтому именно то, что вы делаете с предыдущими примерами.

Действительно, в Python мы используем self как this, но это немного больше. 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)

Это точно так же. Первый аргумент метода объекта является текущим объектом, мы только называем это self в качестве конвенции. И вы добавляете только переменную к этому объекту, так же, как вы делали бы это извне.

Теперь о переменных класса.

Когда вы выполните:

class Example(object):
    itsProblem = "problem"


theExample = Example()
print(theExample.itsProblem)

Вы заметите, что мы сначала задали переменную класса, затем мы обращаемся к переменной объекта (экземпляра). Мы никогда не устанавливаем эту переменную объекта, но она работает, как это возможно?

Ну, Python пытается получить первую объектную переменную, но если она не сможет ее найти, она даст вам переменную класса. Предупреждение: переменная класса распределяется между экземплярами, а объектная переменная - нет.

В качестве вывода никогда не используйте переменные класса для установки значений по умолчанию для переменных объекта. Для этого используйте __init__.

В конце концов вы узнаете, что классы Python являются экземплярами и, следовательно, самими объектами, что дает новое понимание для понимания вышеизложенного. Вернитесь и прочитайте это позже, как только вы это осознаете.

Ответ 2

Вы объявляете локальную переменную, а не переменную класса. Чтобы установить переменную экземпляра (атрибут), используйте

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

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

Чтобы установить переменную класса (статический член a.k.a.), используйте

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.

Ответ 3

Если у вас есть функция экземпляра (то есть та, которая передается 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 ...

Ответ 4

Реализуйте оператор return, как в примере ниже! Вы должны быть хорошими. Я надеюсь, что это помогает кому-то..

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


theExample = Example()
print theExample.the_example()