2015-06-18 2 views
0

Я передаю функцию как параметр конструктору класса. Конструктор сохраняет его в переменной экземпляра, и другие методы класса хотят его вызвать.Как вызвать функцию, сохраненную в переменной экземпляра класса Python

class ComboList(list) : 
    def __init__(self,a,b,kg) : 
     list.__init__(self) 
     self.__kg = kg 
     # More stuff follows 

Когда я пытаюсь вызвать функцию в другом методе, например:

x = self.__kg('a') 

я получаю "{AttributeError} 'объект не имеет атрибута '__kg'."

Когда я оцениваю вызов функции в окне «Вычисление выражения IDE», я получаю то же самое. Но когда я оцениваю сам переменный экземпляр («сами .__ кг»), я получаю:

result = {function} <function <lambda> at 0x0000000002ED5C18> 

... так что кажется, что атрибут __kg является определена.

Что происходит не так?

Я могу вызвать функцию, указав параметр - не проблема.

kg(a') 

Я также могу присвоить значение параметра переменной метода и вызвать переменную - без проблем.

_kag = kg 
_kag('a') 

Это только ссылка на переменную экземпляра, которая не работает.

+0

Это [** название mangling **] (https://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_Python) - попробуйте '_ComboList__kg'. Или просто выровняйте двойные подчеркивания. – jonrsharpe

+0

Можете ли вы, пожалуйста, обновить код, в котором вы создаете объект 'ComboList', и вызывать функцию kg? –

+0

jonrsharpe, это имеет смысл, но это удивительно. Я знаю, что изменение имени должно заставить переменных трудно случайно получить за пределами объекта области, где они определены. Я не ожидал, что это сильно изменится в пределах объекта области. @Anand, неясно, какое обновление вы имеете в виду. Код не изменился каким-либо соответствующим образом. Если это все еще нужно, проясните, и я постараюсь разместить вас. –

ответ

1

Всякий раз, когда переменная имеет двойное подчеркивание в классе, Python будет ссылаться на изменение имени (см. Python documentation on classes). Использование двойных подчеркиваний в значительной степени заключается только в том, чтобы избежать конфликтов имен с подклассами или сделать переменную «действительно частной». (См. PEP8 для получения дополнительных предложений по стилю).

Если вы хотите, чтобы другие унаследованные подклассы использовали вашу личную переменную, вы можете использовать одно единственное подчеркивание (_kg) или использовать декоратор @property.

Заканчивать этот действительно тупой пример:

class ComboList(list) : 
    def __init__(self,a,b,kg) : 
     list.__init__(self) 
     self.__kg = kg 
     # More stuff follows 

    @property 
    def kg(self): 
     return(self.__kg) 

my_list = ComboList(1,2,'This will be printed') 
print(my_list.kg) 
1

Не используйте двойное подчеркивание, что делает питон сделать некоторые магии и добавляет к имени класса именам переменных (называется имя коверкая). Просто используйте одиночное подчеркивание вместо двойного.