Все function
-значимые атрибуты класса являются методами экземпляра, независимо от того, определена ли функция внутри или вне оператора class
.
И a.baz
, и a.bar
запускают протокол дескриптора, который возвращает результат bar.__get__(a, A)
, который вызывается, который пытается вызвать bar
с двумя аргументами.
Если это так, вы можете явно запустить это поведение метода без определения каких-либо атрибутов класса.
def bar(a, b):
print(f'"Object": {a}')
print(f'Argument: {b}')
class Foo:
pass
f = Foo()
bar.__get__(f, Foo)(2)
производит вывод
Object: <__main__.Foo object at 0x108cb5e80>
Argument: 2
То, что вы хотите, это метод stati c, так что при его вызове базовой функции не даются никакие неявные аргументы, только те аргументы, которые передаются самому методу.
class Foo:
baz = staticmethod(bar)
f = Foo()
f.baz(1, 2) # bar gets arguments 1 and 2, not f, 1, and 2.
staticmethod.__get__
просто возвращают саму базовую функцию, а не method
объект, который оборачивает функцию.
Относительно отличается от поведения os.open
, вы должны признать, что os.open
не имеет тот же тип, что и значение, созданное оператором def
:
>>> import os
>>> def bar(): pass
...
>>> type(os.open)
<class 'builtin_function_or_method'>
>>> type(bar)
<class 'function'>
Тип builtin_function_or_method
не имеет реализовать __get__
, поэтому при доступе к такому значению через поиск атрибутов ничего не происходит.