bound与unbound
通常认为实例方法是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)还是能得到类中所有属性,有点掩耳盗铃的感觉,待继续研究