В чем разница между переменными класса разных типов?

Во-первых, существует класс A с двумя переменными класса и двумя переменными экземпляра:

 In [1]: def fun(x, y): return x + y In [2]: class A: ...: cvar = 1 ...: cfun = fun ...: def __init__(self): ...: self.ivar = 100 ...: self.ifun = fun 

Мы видим, что переменная класса и переменная экземпляра типа int отлично работают:

 In [3]: a = A() In [4]: a.ivar, a.cvar Out[4]: (100, 1) 

Однако все изменилось, если мы проверим переменные типа функции:

 In [5]: a.ifun, a.cfun Out[5]: (<function __main__.fun>, <bound method A.fun of <__main__.A instance at 0x25f90e0>>) In [6]: a.ifun(1,2) Out[6]: 3 In [7]: a.cfun(1,2) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) /home/future/<ipython-input-7-39aa8db2389e> in <module>() ----> 1 a.cfun(1,2) TypeError: fun() takes exactly 2 arguments (3 given) 

Я знал, что python перевел a.cfun(1,2) в A.cfun(a,1,2) а затем поднял ошибку.

Мой вопрос : поскольку cvar и cfun являются переменными класса, почему python относится к ним разным образом?

One Solution collect form web for “В чем разница между переменными класса разных типов?”

На самом деле функция, назначенная члену класса, остается функцией:

 def x():pass class A: f = x e = None g = None print(A.__dict__['f']) # <function x at 0x10e0a6e60> 

Он преобразуется «на лету» в объект метода, когда вы извлекаете его из экземпляра:

 print(A().f) # <bound method Ax of <__main__.A instance at 0x1101ddea8>> 

http://docs.python.org/2/reference/datamodel.html#the-standard-type-hierarchy "Пользовательские методы":

Пользовательские объекты метода могут создаваться при получении атрибута класса (возможно, через экземпляр этого класса), если этот атрибут представляет собой определяемый пользователем объект функции, несвязанный определяемый пользователем объект метода или объект метода класса. Обратите внимание, что преобразование объекта объекта в объект (unbound или bound) происходит каждый раз, когда атрибут извлекается из класса или экземпляра.

Это преобразование происходит только с функциями, назначенными классу, а не экземпляру. Обратите внимание, что это было изменено в Python 3, где Class.fun возвращает нормальную функцию, а не «несвязанный метод».

Что касается вашего вопроса, почему это необходимо, объект метода по существу является закрытием, которое содержит функцию вместе с ее контекстом выполнения («self»). Представьте, что у вас есть объект и где-то использовать его метод. Во многих других языках вам необходимо передать указатели объектов и методов или создать закрытие вручную. Например, в javascript:

  myListener = new Listener() something.onSomeEvent = myListener.listen // won't work! something.onSomeEvent = function() { myListener.listen() } // works 

Python управляет этим за кулисами:

  myListener = Listener() something.onSomeEvent = myListener.listen // works 

С другой стороны, иногда практично иметь «голые» функции или «чужие» методы в классе:

  def __init__(..., dir, ..): self.strip = str.lstrip if dir == 'ltr' else str.rstrip ... def foo(self, arg): self.strip(arg) 

Это вышеприведенное соглашение (класс vars => методы, функции экземпляра vars =>) обеспечивает удобный способ для обоих.

Излишне добавлять, как и все остальное в python, можно изменить это поведение, то есть написать класс, который не преобразовывает его функции в методы и возвращает их как есть.

  • Почему type (classInstance) возвращает экземпляр?
  • Как получить доступ к «себе» в рамках класса?
  • Получение имени экземпляра внутри класса __init __ ()
  • В цикле в Python я назначаю новый экземпляр класса той же переменной, но он продолжает указывать на старый экземпляр?
  • Определите, является ли переменная Python экземпляром встроенного типа
  • Как создать экземпляр списка Python без синтаксического сахара
  • В Python, как проверить, существует ли экземпляр моего класса?
  • объекты метода против объектов-функций, экземпляры класса Python vs class
  • Python - лучший язык программирования в мире.