vitus_wagner: My photo 2005 (Default)
[personal profile] vitus_wagner
Имеем вот такой файлик:
# -*- 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, in 
    x()
TypeError: 'Callme' object is not callable


python3 call.py
foo
bar


Что я делаю не так?
Я, конечно могу обмануть питон, объявив
def __call__(self, *args):
     return self.action(*args)

а в конструкторе присваивать self.action. Но как-то оно странно. Всю жизнь думал что в питоне все логично, и если можно методы присваивать, то любые можно.

О, оказывается можно присвоить self.__class__.__caller__. Тогдавсе работает.
И меня в принципе устраивает. Поскольку тот объект, которому я хочу менять поведение при вызове в программе
в любом случае ровно один.

Date: 2020-04-22 08:17 pm (UTC)
ext_646638: (Default)
From: [identity profile] rdia.livejournal.com
Мне всё время казалось, что вот если какое-то место Питона неочевидно, его использовать нельзя.

Date: 2020-04-22 08:19 pm (UTC)
From: [personal profile] kouzdra
Случайно не в том ли, что в первой ветке пропущен один подчерк?

3.3. Special method names

Date: 2020-04-22 09:54 pm (UTC)
phd_ru: (Default)
From: [personal profile] phd_ru
https://docs.python.org/3/reference/datamodel.html#special-method-names

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)
phd_ru: (Default)
From: [personal profile] phd_ru
Кстати, перепиши class Callme(object): и попробуй с Python 2.7. Будет то же самое, как в 3-ем.

В питоне все логично

Date: 2020-04-22 10:03 pm (UTC)
phd_ru: (Default)
From: [personal profile] phd_ru
> Всю жизнь думал что в питоне все логично

Главная ошибка здесь. В Питоне ничего не логично, похожие синтаксические конструкции в разных местах могут приводить к разным эффектам. Всегда надо помнить про отличия старых классов от новых, три пространства имён и их странные взаимодействия…

Date: 2020-04-22 10:13 pm (UTC)
palmas1: (Default)
From: [personal profile] palmas1
А там не опечатка? "olass Callme:"

Date: 2020-04-23 12:11 am (UTC)
elentin: (Default)
From: [personal profile] elentin
Витус, ты шутишь?

В Питоне
a = 5
b = a

приводит к тому, что появляются 2 переменные (места в памяти), и в них обеих лежит 5 (поправь меня, если это не так), но
s1 = [1, 2, 3, 4, 5]
s2 = s1


не приводит к выделению новой памяти и копированию списка, а приводит к копированию указателя на первый список. Вот это - логично?
Edited Date: 2020-04-23 12:15 am (UTC)

Date: 2020-04-23 09:12 am (UTC)
elentin: (Default)
From: [personal profile] elentin
Я в данном случае имею в виду, что кажущиеся похожими операции

что-то1 = что-то2

и

список1 = список2

Не приводят к одинаковому по смыслу результату.
Edited Date: 2020-04-23 09:13 am (UTC)

Связывание

Date: 2020-04-23 09:23 am (UTC)
phd_ru: (Default)
From: [personal profile] phd_ru
В Питоне нет операции присваивания!

Re: Связывание

Date: 2020-04-23 11:41 am (UTC)
pilpilon: (Default)
From: [personal profile] pilpilon
теперь есть. уже полгода как.

Re: Связывание

Date: 2020-04-23 11:45 am (UTC)
phd_ru: (Default)
From: [personal profile] phd_ru
:= не больше присваивание, чем =.

Profile

vitus_wagner: My photo 2005 (Default)
vitus_wagner

June 2025

S M T W T F S
1 23 4567
891011121314
15161718192021
22232425262728
2930     

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 4th, 2025 06:12 am
Powered by Dreamwidth Studios