2016-08-23 6 views
1

в последней 2.7.x Python:Как указать переменную как переменную-член класса или экземпляр класса?

  1. Учитывая любой переменной члена внутри определения класса, является переменная-член всегда на уровне класса, в том смысле, что она является одной переменной совместно всеми экземплярами класса?

  2. В определении класса, как я могу указать

    • , какие переменные-члены в определении класса принадлежат к классу и, таким образом, разделяемое всеми экземплярами класса, и
    • которые принадлежат определенному экземпляру класса, а не другому экземпляру класса?
  3. Как я могу обратиться к переменной-члену класса?

    Как я могу ссылаться на переменную-член экземпляра класса?

  4. Ответы на вышеуказанные вопросы появляются где-то на официальной ссылке на языке python https://docs.python.org/2/reference/? Я не могу найти их там.

Спасибо.

+0

В общем, вы не можете сказать. Но t тоже не имеет значения. – Daniel

+0

Возможно, вы ищете ["9.3.5. Переменные класса и экземпляра"] (https://docs.python.org/2/tutorial/classes.html#class-and-instance-variables), который охватывает большую часть что вы просите. –

+0

Как вы можете сказать, в каком контексте? Программно проверять его? Посмотрите на исходный код? –

ответ

1

Здесь вы можете использовать «переменную класса» и «переменную экземпляра», так как это обычный язык в python.

class Foo(object): 

    var1 = "I'm a class variable" 

    def __init__(self, var2): 
     self.var2 = var2 # var2 is an instance variable 

Единственное правило обзорного вам действительно нужно знать, питон порядок поиска имен - «LEGB», для местного, ограждающего, Global и BUILTIN.

Переменная класса с областью var1 все еще нуждается в поиске по "get attribute", вы можете получить доступ только к этому значению Foo.var1 или self.var1. Конечно, вы также можете получить доступ к нему в другом месте внутри блока определения класса, но это всего лишь пример использования из области «Локальный».

Когда вы видите self.var1, вы не можете сразу узнать, является ли это экземпляром или переменной класса (и, фактически, если имя привязано к объекту вообще!). Вы только знаете, что атрибут get проверяется на самом объекте, прежде чем он будет опробован классом.

В самом деле, переменная экземпляра может теневой класс переменный с тем же именем:

>>> f1 = Foo(var2='f1_2') 
>>> f2 = Foo(var2='f2_2') 
>>> f2.var1 
"I'm a class variable" 
>>> f2.var1 = "Boom!" # this shadows the class variable 
>>> f1.var1, Foo.var1, f2.var1 # but: the class variable still exists 
("I'm a class variable", "I'm a class variable", 'Boom!') 
>>> del f2.var1 # restores the name resolution on the Foo object 
>>> f2.var1 
"I'm a class variable" 

мудрить, мы можем написать фантазии кода, который делает переменный класс ведет себя скорее как переменный экземпляр; примечательным примером являются «поля» ORM. Например, в Django вы можете определить целое поле в классе model, однако при поиске этого имени в экземпляре модели вы получите возвращаемое фактическое целое число (а не объект IntegerField).

Если вы заинтересованы в этом расширенном использовании доступа к атрибутам, прочитайте на descriptor protocol.Для мирских классов вы можете смело игнорировать эти детали, но стоит знать, что обычное разрешение переменных экземпляра, а затем переменных класса имеет более низкий приоритет, чем любые дескрипторы, которые, возможно, были определены в классе.

+0

спасибо. правильно ли переменная экземпляра может быть определена только внутри тела функции '_init (self, ...)'? – Tim

+0

@Tim Может быть, вам будет проще подумать о том, где вы можете и не можете создать переменную класса, поскольку это намного более ограничено. Переменные экземпляра могут создаваться в разных местах. Возможно, вам захочется прочитать некоторые более сложные вещи, такие как [дескрипторы] (http://nedbatchelder.com/blog/201306/explaining_descriptors.html) и [метаклассы] (https://jakevdp.github.io/blog/2012/12/01/a-primer-on-python-metaclasses /), потому что это даст вам намного лучшее представление о базовом оборудовании и о том, как он обычно используется. –

+0

@ Тим Нет, это неправильно. Вы также можете создавать их вне '__init__'. – wim

Смежные вопросы