Вот почему оно так?
Apr. 22nd, 2020 11:02 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Имеем вот такой файлик:
Запускаем
Что я делаю не так?
Я, конечно могу обмануть питон, объявив
а в конструкторе присваивать self.action. Но как-то оно странно. Всю жизнь думал что в питоне все логично, и если можно методы присваивать, то любые можно.
О, оказывается можно присвоить self.__class__.__caller__. Тогдавсе работает.
И меня в принципе устраивает. Поскольку тот объект, которому я хочу менять поведение при вызове в программе
в любом случае ровно один.
# -*- encoding: utf-8 -*- from __future__ import print_function class Callme: def __init__(self, arg): if arg: self.__call__ = self.foo else: self.__call__ = self.bar def foo(self): print("foo") def bar(self): print("bar") x = Callme(True) x() y = Callme(False) y()
Запускаем
python3 call.py Traceback (most recent call last): File "caller.py", line 17, inx() TypeError: 'Callme' object is not callable
python3 call.py foo bar
Что я делаю не так?
Я, конечно могу обмануть питон, объявив
def __call__(self, *args): return self.action(*args)
а в конструкторе присваивать self.action. Но как-то оно странно. Всю жизнь думал что в питоне все логично, и если можно методы присваивать, то любые можно.
О, оказывается можно присвоить self.__class__.__caller__. Тогдавсе работает.
И меня в принципе устраивает. Поскольку тот объект, которому я хочу менять поведение при вызове в программе
в любом случае ровно один.
no subject
Date: 2020-04-22 08:17 pm (UTC)no subject
Date: 2020-04-22 08:20 pm (UTC)no subject
Date: 2020-04-22 08:19 pm (UTC)no subject
Date: 2020-04-22 08:22 pm (UTC)3.3. Special method names
Date: 2020-04-22 09:54 pm (UTC)A class can implement certain operations that are invoked by special syntax (such as arithmetic operations or subscripting and slicing) by defining methods with special names.
Выделено мной — phd.
Поиск магических методов выполняется в
type(x)
, т.е. сначала в классе, потом в метаклассе, но не в экземпляре. Оптимизация.Python 2
Date: 2020-04-22 09:57 pm (UTC)class Callme(object):
и попробуй с Python 2.7. Будет то же самое, как в 3-ем.В питоне все логично
Date: 2020-04-22 10:03 pm (UTC)Главная ошибка здесь. В Питоне ничего не логично, похожие синтаксические конструкции в разных местах могут приводить к разным эффектам. Всегда надо помнить про отличия старых классов от новых, три пространства имён и их странные взаимодействия…
no subject
Date: 2020-04-22 10:13 pm (UTC)no subject
Date: 2020-04-23 12:11 am (UTC)В Питоне
приводит к тому, что появляются 2 переменные (места в памяти), и в них обеих лежит 5 (поправь меня, если это не так), но
не приводит к выделению новой памяти и копированию списка, а приводит к копированию указателя на первый список. Вот это - логично?
no subject
Date: 2020-04-23 05:42 am (UTC)no subject
Date: 2020-04-23 09:12 am (UTC)что-то1 = что-то2
и
список1 = список2
Не приводят к одинаковому по смыслу результату.
Связывание
Date: 2020-04-23 09:23 am (UTC)Re: Связывание
Date: 2020-04-23 11:41 am (UTC)Re: Связывание
Date: 2020-04-23 11:45 am (UTC):=
не больше присваивание, чем=
.no subject
Date: 2020-04-23 09:36 am (UTC)И для того, чтобы в этом убедиться, есть операция is.
В обоих случах две переменные становятся ссылками на один и тот же объект.
И если мы объект, на который указывает одна переменная, модифицируем, модифицируется и другой объект.
Правда, в случае списка модификация - штатная операция. а в случае числа - это извратиться надо.
Но зато тогда изменится не только то, что возвращают, переменные. но и то, на что указывает числоваая константа (причем с любой системой счисления).
И будет вот такая картина: