в Python, как получить доступ к переменной: в файле модуля, в классе, не начиная с self [duplicate]

В документации jQuery.fn.on есть хорошее объяснение.

Короче:

Обработчики событий привязаны только к выбранные в данный момент элементы; они должны существовать на странице, когда ваш код делает вызов .on().

Таким образом, в следующем примере #dataTable tbody tr должен существовать до генерации кода.

$("#dataTable tbody tr").on("click", function(event){
    console.log($(this).text());
});

Если на страницу вводится новый HTML-код, предпочтительнее использовать делегированные события для присоединения обработчика событий, как описано ниже.

Делегированные события имеют то преимущество, что они могут обрабатывать события от элементов потомков, которые будут добавлены в документ позже. Например, если таблица существует, но строки добавляются динамически с использованием кода, следующее будет обрабатывать ее:

$("#dataTable tbody").on("click", "tr", function(event){
    console.log($(this).text());
});

В дополнение к их способности обрабатывать события на дочерних элементах, которые еще не созданы, другим преимуществом делегированных событий является их потенциал для гораздо более низких накладных расходов, когда необходимо контролировать многие элементы. В таблице данных с 1000 строками в tbody первый пример кода прикрепляет обработчик к 1000 элементам.

Подход с делегированными событиями (второй пример кода) прикрепляет обработчик события только к одному элементу , tbody, и событию нужно только выровнять один уровень (от щелчка tr до tbody).

Примечание. Делегированные события не работают для SVG .

49
задан Ciro Santilli 新疆改造中心 六四事件 法轮功 28 March 2017 в 13:49
поделиться

4 ответа

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

В вашем примере 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 

Печать

True

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

Действительно, в Python мы используем self как this, но это немного больше. 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 object является текущий объект, мы называем его self как соглашение. И вы добавляете только переменную к этому объекту, так же, как вы делали бы это извне.

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

Когда вы это сделаете:

class Example(object):
    itsProblem = "problem"


theExample = Example()
print(theExample.itsProblem)

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

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

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

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

94
ответ дан bentsai 19 August 2018 в 08:51
поделиться
  • 1
    +1 для init . Вот для чего это. – Abizern 8 August 2010 в 15:28
  • 2
    вы говорите: «theExample.itsProblem автоматически устанавливается равным Example.itsProblem, но не является той же самой переменной вообще и может быть независимо изменена», - но это не совсем правильно, и ваша фраза вводит в заблуждение. Надеюсь, вы знаете, что там происходит, поэтому я предлагаю перефразировать это: & quot; it есть одна и та же переменная, но ее можно перестроить независимо для каждого объекта & quot ;. – jsbueno 8 August 2010 в 15:39
  • 3
    Да, но привязка - это понятие для кого-то другого языка программирования, такого как Java или C (как я подозреваю, OP), который полностью неизвестен. Затем я хотел бы объяснить, что такое привязка, а затем - поздняя привязка, а затем проблема со ссылками на изменяемые объекты. Это было бы слишком долго. Я думаю, что когда-нибудь вы должны пожертвовать точностью на алтаре понимания. – e-satis 9 August 2010 в 13:57
  • 4
    Существует также (я думаю, что это может быть 2,7 +) декоратор @classmethod, заслуживающий внимания. интересное обсуждение здесь - stackoverflow.com/questions/12179271/… – jsh 8 March 2013 в 18:55
  • 5
    name-binding: Я думаю, что это плохая идея давать ложные утверждения, независимо от уровня. Я предлагаю это небольшое редактирование: но будьте осторожны с этим, поскольку theExample.itsProblem автоматически устанавливается равным Example.itsProblem, но, с практической точки зрения *, не является одной и той же переменной и может быть изменен независимо. *: на самом деле он начинается как один и тот же объект, но его очень легко случайно изменить, если вы не понимаете имя имени Python] – n611x007 22 April 2014 в 21:45

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

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.
8
ответ дан kennytm 19 August 2018 в 08:51
поделиться
  • 1
    За исключением того, что переменные класса объявляются один раз на уровне класса . Ваш путь сбрасывает его при каждом запуске, это действительно не то, что вы хотите. Также см. stackoverflow.com/questions/2709821/python-self-explained для обоснования явного «я». – user 8 August 2010 в 15:07

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

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

    theExample = Example()
    print theExample.the_example()
-1
ответ дан mayor 19 August 2018 в 08:51
поделиться
  • 1
    Вы должны исправить свой отступ кода. Есть также превосходные ответы на этот вопрос, и ваш ответ является основным вариантом ответов, а не альтернативным решением ... – HEADLESS_0NE 24 May 2017 в 15:13

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

Например, в приведенном ниже коде торнадо создает экземпляр для обрабатывать запросы, но мы можем получить класс 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 ...
0
ответ дан zagyi 19 August 2018 в 08:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: