Теперь, когда ясно, что такое метакласс , есть связанная концепция, которую я использую все время, не зная, что это на самом деле означает.
Я полагаю, что все однажды допустили ошибку с круглыми скобками, что привело к исключению «объект не может быть вызван». Более того, использование __init__
и __new__
привести к удивлению, для чего __call__
может быть использован этот кровавый .
Не могли бы вы дать мне некоторые объяснения, в том числе примеры с магическим методом?
Ответы:
Вызываемым является все, что можно назвать.
Встроенный отозваны (PyCallable_Check в objects.c) проверки , если аргумент является:
__call__
методом илиМетод
__call__
называется ( согласно документации )пример
источник
callable
на самом деле говорит вам, если что-то вызывается или нет, в то время как проверка для__call__
вас ничего не говорит; Если объектo
предоставляет__getattribute__
или__getattr__
,hasattr(o, '__call__')
может вернуть True, он всеo
равно не будет вызываться из-за пропуска Python__getattribute__
и__getattr__
для вызовов. Таким образом, единственный реальный способ проверить, является ли что-то вызываемым, - это EAFP.callable()
Python 3.x : « Эта функция была сначала удалена в Python 3.0, а затем возвращена в Python 3.2. ».tp_call
проверяется только наличие . Смотрите реализацию PyCallable_Check , это 3 строки.Из исходного кода Python object.c :
Это говорит:
__call__
атрибут.x
может быть вызван, еслиx->ob_type->tp_call != NULL
Описание
tp_call
поля :Вы всегда можете использовать встроенную
callable
функцию, чтобы определить, является ли данный объект вызываемым или нет; или еще лучше просто позвони и поймайTypeError
позже.callable
удаляется в Python 3.0 и 3.1, используйтеcallable = lambda o: hasattr(o, '__call__')
илиisinstance(o, collections.Callable)
.Пример, упрощенная реализация кэша:
Использование:
Пример из стандартной библиотеки, файл
site.py
, определение встроенныхexit()
иquit()
функций:источник
def f(): ...
и объектов класса , таким , какclass C: ...
например,f
,''.strip
,len
иC
все могут быть отозваны. Экземпляры, у которых есть__call__()
метод в своем классе, относительно редки.Вызываемый объект - это объект, который позволяет вам использовать круглые скобки () и в конечном итоге передавать некоторые параметры, как функции.
Каждый раз, когда вы определяете функцию, python создает вызываемый объект. Например, вы можете определить функцию func следующим образом (это то же самое):
Вы можете использовать этот метод вместо методов типа doit или run , я думаю, что более просто увидеть obj (), чем obj.doit ()
источник
Позвольте мне объяснить в обратном направлении:
Учти это...
... как синтаксический сахар для:
Где
foo
может быть любой объект, который отвечает__call__
. Когда я говорю любой объект, я имею в виду это: встроенные типы, ваши собственные классы и их экземпляры.В случае встроенных типов, когда вы пишете:
Вы по существу делаете:
Вот почему у вас нет
foo = new int
в Python: вы просто заставляете объект класса возвращать его экземпляр__call__
. Способ, которым Python решает эту проблему, на мой взгляд, очень элегантен.источник
type(int).__call__(int, '10')
иtype(unicode).__call__(unicode, '10')
. Dunders всегда вызывается в их классе, а не через экземпляр. И они никогда не проходят через метакласс. В большинстве случаев это просто придурок, но иногда это важно.Callable - это объект, у которого есть
__call__
метод. Это означает, что вы можете подделывать вызываемые функции или делать изящные вещи, такие как Partial Function Application, где вы берете функцию и добавляете что-то, что улучшает ее или заполняет некоторые параметры, возвращая что-то, что может быть вызвано по очереди (так называемое Curry в кругах функционального программирования). ).Некоторые типографские ошибки приводят к тому, что интерпретатор пытается вызвать то, что вы не хотели, например (например) строку. Это может привести к ошибкам, когда интерпретатор пытается выполнить не вызываемое приложение. Вы можете увидеть это в интерпретаторе python, выполнив что-то вроде стенограммы ниже.
источник
__call__
делает любой объект вызываемым как функцию.Этот пример выведет 8:
источник
Проще говоря, «вызываемый» - это то, что можно вызвать как метод. Встроенная функция «callable ()» сообщит вам, кажется ли что-то вызываемым, так же как и проверка свойства вызова . Функции могут вызываться так же, как и классы, экземпляры классов могут быть вызваны. Подробнее об этом здесь и здесь .
источник
В Python вызываемый объект - это объект, тип которого имеет
__call__
метод:Так просто, как, что :)
Это, конечно, может быть перегружено:
источник
Проверка функции или метода класса является вызываемой или нет, это означает, что мы можем вызвать эту функцию.
источник
callable(obj.__init___)
что нет лишнего подчеркивания (как в AttributeError)? Если это не так, вы уверены, что ответ неTrue
для этого?Это то, что вы можете поставить "(args)" после и ожидать, что это сработает. Вызываемый - это обычно метод или класс. Методы вызываются, классы создаются.
источник
callables реализуют
__call__
специальный метод, поэтому любой объект с таким методом может быть вызван.источник
__call__
, не будет вызываться, если класс не определяет такой метод.Callable - это тип или класс «встроенной функции или метода» с вызовом метода.
Пример: print является вызываемым объектом. Со встроенной функцией __call__ Когда вы вызываете функцию print , Python создает объект типа print и вызывает его метод __call__, передавая параметры, если они есть.
Спасибо. С уважением, Марис
источник
print
функцию, Python создает объект типа print и вызывает его метод__call__
». Python не создает объект печати. Это просто вызывает что-то эквивалентноеtype(print).__call__(print, *args, **kwargs)
. И первое предложение не имеет особого смысла. Вы, кажется, путаете вызываемый объект и «вызываете» функцию.