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

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

theExample = Example()
print(theExample.itsProblem)

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

def return_itsProblem(self):
    return itsProblem

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

5 ответов

Решение

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

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

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

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.

Если у вас есть функция экземпляра (то есть та, которая передается self), вы можете использовать self, чтобы получить ссылку на класс, используя self.__ __class__ __

Например, в приведенном ниже коде торнадо создает экземпляр для обработки запросов 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 ...

Если у тебя есть@classmethodstatic , у вас всегда есть класс в качестве первого параметра:

      class Example(object):
    itsProblem = "problem"

    @classmethod
    def printProblem(cls):
        print(cls.itsProblem)

Example.printProblem()

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

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

    theExample = Example()
    print theExample.the_example()
Другие вопросы по тегам