通常认为实例方法是bound的,而类方法是unbound的,这种说法也没错,只是对于不同类型变量来说,结果是不同的
class A(object):
\"\"\"test class\"\"\"
_instance = None
def __private(self):
pass
def _protect(self):
pass
def fs(self):
pass
@staticmethod
def sm():
pass
@classmethod
def fc(cls):
pass
测试一下, 结果显示的都是bound method
>>> a = A()
>>> a.fs
>
>>> a.fc
>
直接从类访问,结果fs
这个实例方法显示的是unbound。可以知道bound的意义并不是始终不变的,对于不同的对象来说意义并不一样。
>>> A.fs
>>> A.fc
>
python里面类方法和实例方法可以等价变换
a.fs()
# equals
A.fs(a)
从描述器的角度看
>>> A.__dict__[\'fs\'].__get__(None, A)
>>> A.__dict__[\'fs\'].__get__(a, A)
>
>>> A.__dict__[\'fc\'].__get__(None, A)
>
不过实例a
调用静态方法会出错(TypeError),因为实例对方法的调用提供了self
参数,但sm
是没有参数的。但是这提供了另一种思路)比如在python的多进程编程中,进程跑的函数如果是实例函数的会因为无法序列化而失败,但如果是staticmethod
就没有问题,静态函数的本质其实也就是普通函数。
所以可以这样
class B(object):
@staticmethod
def run(inst):
inst.foo()
def foo(self):
print \'foo\'
b = B()
B.run(b)
在2.x中区分实例函数和类函数可以用im_self
>>> A.fs.im_self
None
>>> A.fc.im_self
至于通过实例引用方法时的im_self
的值,大家自己可以探索下
使用dir
函数
>>> dir(A)
[\'_A__private\',
\'__class__\',
\'__delattr__\',
\'__dict__\',
\'__doc__\',
\'__format__\',
\'__getattribute__\',
\'__hash__\',
\'__init__\',
\'__module__\',
\'__new__\',
\'__reduce__\',
\'__reduce_ex__\',
\'__repr__\',
\'__setattr__\',
\'__sizeof__\',
\'__str__\',
\'__subclasshook__\',
\'__weakref__\',
\'_instance\',
\'_protect\',
\'fc\',
\'fs\',
\'sm\']
2 使用inspect.getmembers
这个除了函数名的字符串以外,连对象的type也得到了,结果更加详细
>>> inspect.getmembers(A)
[(\'_A__private\', ),
(\'__class__\', type),
(\'__delattr__\', ),
(\'__dict__\',
,
\'__dict__\': ,
\'__doc__\': \'test class\',
\'__module__\': \'__main__\',
\'__weakref__\': ,
\'_instance\': None,
\'_protect\': ,
\'fc\': ,
\'fs\': ,
\'sm\': }>),
(\'__doc__\', \'test class\'),
(\'__format__\', ),
(\'__getattribute__\', ),
(\'__hash__\', ),
(\'__init__\', ),
(\'__module__\', \'__main__\'),
(\'__new__\', ),
(\'__reduce__\', ),
(\'__reduce_ex__\', ),
(\'__repr__\', ),
(\'__setattr__\', ),
(\'__sizeof__\', ),
(\'__str__\', ),
(\'__subclasshook__\', ),
(\'__weakref__\', ),
(\'_instance\', None),
(\'_protect\', ),
(\'fc\', >),
(\'fs\', ),
(\'sm\', )]
a = A()
callable(getattr(a, \'testattr\', None))
获得一个对象中所有可调用的方法
[method for method in dir(object) if callable(getattr(object, method))]
重写__dict__
或者__dir__
class C(object):
__dict__ = {}
def __dir__(self):
return [\'cherry\']
注意,这里的__dict__
不是类的,是实例的,类的__dict__
是不可写的,不信可以试试__dir__
很奇怪,如果dir
函数用在C
的实例上,确实会返回[\'cherry\']
,但dir(C)
还是能得到类中所有属性,有点掩耳盗铃的感觉,待继续研究