tips: There is
no unbounded
method inPython 3
https://bugs.python.org/issue23702
类的属性都是放在 __dict__
中的
在Python中使用描述器
来表示具有“绑定”行为
的对象属性
,
使用描述器协议方法
来控制对具有绑定行为属性
的访问,
这些描述器协议方法包括:__get__()
、__set__()
和__delete__()
。
py2+
中存在 unbound method
定义在类中的普通函数, 是
unbound method
, 没有 绑定instance
class F(object):
def foo_normal_function():
print "foo_normal_function"
print(F.foo_normal_function)
print(F.__dict__["foo_normal_function"].__get__(None, F) )
print(F().foo_normal_function)
print(F.__dict__["foo_normal_function"].__get__(F(), F) )
# <unbound method F.foo_normal_function>
# <unbound method F.foo_normal_function>
# <bound method F.foo_normal_function of <__main__.F object at 0x03AE1910>>
# <bound method F.foo_normal_function of <__main__.F object at 0x03AE14D0>>
普通方法
,实例方法
,类方法
,静态方法
的调用
# coding: utf-8
class F():
def foo_normal_function():
print "foo_normal_function"
def foo_instance(self):
print "call foo_instance"
@classmethod
def foo_classmethod(cls):
print "call foo_classmethod"
@staticmethod
def foo_staticmethod():
print "call foo_staticmethod"
# F.foo_staticmethod() # call foo_staticmethod
# F.__dict__["foo_staticmethod"].__get__(None, F)() # call foo_staticmethod
# F.foo_classmethod()
# F.__dict__["foo_classmethod"].__get__(None, F)()
# F.foo_instance(F())
# F().foo_instance()
# F.__dict__["foo_instance"].__get__(None, F)(F())
# F.__dict__["foo_instance"].__get__(F(), F)()
# 这里把F()实例 绑定给实例方法
# F().foo_normal_function(F()) # TypeError: foo_normal_function() takes no arguments (2 given)
# F.__dict__["foo_normal_function"].__get__(F(), F)(F()) # TypeError: foo_normal_function() takes no arguments (2 given)
有装饰器 @staticmethod
, @classmethod
装饰, (这里的装饰器是描述器
), 调用描述器的__get__
方法
class staticmethod(object):
"""
staticmethod(function) -> method
Convert a function to be a static method.
A static method does not receive an implicit first argument.
To declare a static method, use this idiom:
class C:
@staticmethod
def f(arg1, arg2, ...):
...
It can be called either on the class (e.g. C.f()) or on an instance
(e.g. C().f()). The instance is ignored except for its class.
Static methods in Python are similar to those found in Java or C++.
For a more advanced concept, see the classmethod builtin.
"""
def __get__(self, *args, **kwargs): # real signature unknown
""" Return an attribute of instance, which is of type owner. """
pass
def __init__(self, function): # real signature unknown; restored from __doc__
pass
@staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass
__func__ = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
__isabstractmethod__ = property(lambda self: object(), lambda self, v: None, lambda self: None) # default
__dict__ = None # (!) real value is ''
py3+
中不存在 unbound method
class F(object):
# 没有self ,cls参数的 普通函数
def foo_normal_function():
print( "foo_normal_function")
# py2
print(F.foo_normal_function) # <unbound method F.foo_normal_function>
# 不可以直接调用 F.foo_normal_function() unbound method foo_normal_function() must be called with F instance as first argument
print(F.__dict__["foo_normal_function"]) # <function foo_normal_function at 0x02C15AF0>
# 可以直接调用 F.__dict__["foo_normal_function"]()
# py3
print(F.foo_normal_function) # <function F.foo_normal_function at 0x0000018797783598>