一个类中如果定义了一个函数__call__那么该类的实例就可以当成函数来调用
例子如下
class Person(object):
def __init__(self,name,gender):
self.name=name
self.gender=gender
def __call__(self,friend):
print("My name is %s..."%self.name)
print("My friend'name is %s..."%friend)
p=Person("Bob",'male')
p("hudahai")
输出为
My name is Bob...
My friend'name is hudahai...
__getattr__和__slots__
如果一个类中有属性__slots__,那么就不能随便给该类添加__slots__值中以外的属性
(在用户自定义的类型中, __slots__ 属性可以改变实例属性的存储方式, 由 dict 变成 tuple, 相关细节在 9.8 节会谈到)
也就是实例属性默认是由dict实现的,而给类添加__slots__,就更改dict的实现方式为由tuple实现
下面实例中
class A(object):
__slots__ = ('a','b')
def __init__(self,a,b):
self.a=a
self.b=b
def mydefault(self):
print("default")
def __getattr__(self, item):
return self.mydefault
a=A(1,2)
a.hu()#对应的输出是"default"
a.c=3#会出现错误,a中不含有属性c
object.__getattr__(self, name)
当一般位置找不到attribute的时候,会调用getattr,返回一个值或AttributeError异常。
object.__getattribute__(self, name)
无条件被调用,通过实例访问属性。如果class中定义了__getattr__(),则__getattr__()不会被调用(除非显示调用或引发AttributeError异常)
object.__get__(self, instance, owner)
如果class定义了它,则这个class就可以称为descriptor。owner是所有者的类,instance是访问descriptor的实例,如果不是通过实例访问,而是通过类访问的话,instance则为None。