isinstance(a, A)这个函数是看a是不是A的实例,子类对象对于父类也是返回True
type(a)返回a的类型
dir(a)获得a的所有方法和属性
getattr(obj,a,b):获取obj的a属性,如果没有则返回默认值b
setattr(obj,a,b):设置obj的a属性为b
hasattr(obj,a):判断obj是否有a 属性
print(isinstance(cat,Animal))#判断一个 print(isinstance('a',(int,float)))#判断多个 print(isinstance('a',(int,float,str))) True False True print(type(cat)) print(type(cat) == Cat) #types里面有很多常量值 import types if type(run) == types.FunctionType: print('run is a function') if type(abs) == types.BuiltinFunctionType: print('abs is builtin function') if type(lambda x:x*x) == types.LambdaType: print("it's a lambda type") if type((x for x in range(10)))==types.GeneratorType: print("it is generate type") <class '__main__.Cat'> True run is a function abs is builtin function it's a lambda type it is generate type dir(stu) #返回一个列表,列表里是一个对象所有的属性和方法 ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_name', '_score', 'getName', 'getScore', 'setName', 'setScore']使用__slots__
__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的
除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__
class Student(object): __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称 s = Student() # 创建新的实例 s.name = 'Michael' # 绑定属性'name' s.age = 25 # 绑定属性'age' s.score = 99 # 绑定属性'score' --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-54-dc0188d637e3> in <module> ----> 1 s.score = 99 # 绑定属性'score' AttributeError: 'Student' object has no attribute 'score'负责把一个方法变成属性调用
getter和setter方法都为属性名将getter方法上标注@property装饰器将setter方法上标注函数名.setter装饰器 class Student1(object): @property def score(self): return self._score @score.setter def score(self, value): if not isinstance(value, int): raise ValueError('score must be an integer!') if value < 0 or value > 100: raise ValueError('score must between 0 ~ 100!') self._score = value s = Student1() s.score = 60 # OK,实际转化为s.set_score(60) s.score # OK,实际转化为s.get_score() 60 s.score = 9999#报错是因为上面的函数抛出了错误 --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-68-883a7d599880> in <module> ----> 1 s.score = 9999#报错是因为上面的函数抛出了错误 <ipython-input-65-4ce4a387ef86> in score(self, value) 10 raise ValueError('score must be an integer!') 11 if value < 0 or value > 100: ---> 12 raise ValueError('score must between 0 ~ 100!') 13 self._score = value ValueError: score must between 0 ~ 100!这个有点令人迷惑,为什么super(A,self).showItself()调用的却不是A的方法,而且A的父类是object,更没有这个方法
实际上这个是按照顺序来选择的,默认的super()调用的是第一个A,然后下一个是B
再python2中这个搜索顺序是深度优先搜索,而在python3中这个顺序是广度优先搜索
class A1(A): def showItself(self): print('A1') class A2(A): def showItself(self): print('A2') class A12(A1,A2): def showItself(self): super().showItself() super(A1,self).showItself() super(A2,self).showItself() a12 = A12() a12.showItself() A1 A2 A用于当使用print的时候就会调用__str__方法去获取字符串
用于当使用交互模式直接输出变量的时候就会调用__repr__方法去获取字符串
class Astr1: def __repr__(self): return "这是__repr__方法的调用" class Astr2: def __str__(self): return "这是__str__方法的调用" print(Astr1()) print(Astr2()) 这是__repr__方法的调用 这是__str__方法的调用 Astr1() 这是__repr__方法的调用 Astr2() <__main__.Astr2 at 0x1c5bda2af48>当对象需要使用for循环的时候,必须要去实现__iter__方法,返回一个迭代对象
然后迭代对象的__next__方法会被调用
class A_iter: a = 0 def __iter__(self): return self def __next__(self): A_iter.a+=1 if A_iter.a>10: raise StopIteration()##终止循环 return A_iter.a a_iter = A_iter() for i in a_iter: print(i,end=" ") 1 2 3 4 5 6 7 8 9 10__getitem__是用于取序列元素的
一般要分为数字和切片,分别处理
class A_getitem: def __getitem__(self,n): if isinstance(n,int):#索引为数字 return n if isinstance(n,slice):#索引为切片 return [x for x in range(n.start,n.stop)] a = A_getitem() print(a[100]) print(a[10:20]) 100 [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]用于返回未定义的参数
__getattribute__与 __getattr__的区别
当每次调用属性时,python会无条件进入__getattribute__中,不论属性存在与否
而__getattr__只会在找不到属性的时候调用
class A_attr: def __getattribute__(self,attr): return attr a = A_attr() print(a.name) name将对象本身视为一个方法,调用的就是__call__
class A_call: def __call__(self): print('__call__方法被调用') a = A_call() a() __call__方法被调用判断对象是否能被作为函数调用使用callable()函数
print(callable("123")) print(callable(a)) False True