系列
issubclass()与isinstance() 判断类对象与类对象或实例的关系
class ParentClass(object):
pass
class ChildClass(ParentClass):
pass
class ThirdClass(object):
pass
# issubclass判断类对象与类对象的关系
print(issubclass(ChildClass, ParentClass)) # True
print(issubclass(ChildClass, (ParentClass, ThirdClass))) # True,后面是个元组,只要满足元组内任意一个父类就为True
# isinstance判断实例对象与类对象的关系
c = ChildClass()
print(isinstance(c, ChildClass)) # True
print(isinstance(c, (ChildClass, ParentClass, ThirdClass))) # True,后面是个元组,只要满足元组内任意一个类就为True
type()获取指定对象的类型
print(type(c)) #<class '__main__.ChildClass'>,获取指定对象的类型
print(type(ChildClass)) #<class 'type'>, 类对象的类型是type
dir()获取对象的所有信息和__dict__获取对象自定义信息
class MyClass(object):
def __init__(self):
self.name = 'cong'
@classmethod
def cm(cls):
pass
@staticmethod
def sm(p1):
print(p1)
# 获取所有属性和方法,类对象结果中不包含实例属性
print(dir(MyClass)) # [...'__subclasshook__', '__weakref__', 'cm'] 获取所有属性和方法
# 获取所有属性和方法, ['__subclasshook__','__weakref__', 'cm', 'name', 'sm']]
print(dir(MyClass()))
# 获取自定义属性和方法
# {'cm': <classmethod object at 0x000002266E1B5710>, 'sm': <staticmethod object at 0x000002266E1B5748>}
print(MyClass.__dict__)
# 获取自定义属性和方法
print(MyClass().__dict__) # {'name': 'cong'}
反射(hasattr,getattr,setattr,delattr)
"""
用于反射,当不知道对象属性或方法的情况下适用
1. hasattr(object,name) 用于判断对象是否有指定的属性或方法
2. getattr(object,name[,default]) 用于获取指定属性的值或方法,getattr(object,name)等价于object.name
3. setattr(object,name,value) 给对象添加或修改指定属性的值或方法,setattr(object,name,value)等价于object.name=value
4. delattr(object,name) 用于删除指定的属性或方法,等价于del object.name
"""
class MyClass(object):
def __init__(self):
self.x = 1
def do_sth(self):
print('do_sth has been called')
mc = MyClass()
# hasattr 用于判断对象是否有指定的属性或方法
print(hasattr(mc, 'x')) # True
print(hasattr(mc, 'do_sth')) # True
print(hasattr(mc, 'Y')) # False
print(getattr(mc, 'x')) # 1
print(getattr(mc, 'Y', 2)) # 2
# <bound method MyClass.do_sth of <__main__.MyClass object at 0x0000020B74C06668>>
print(getattr(mc, 'do_sth'))
# 方法获取后,这里可以直接调用
f = getattr(mc, 'do_sth')
f() # do_sth has been called
setattr(mc, 'x', 6)
print(mc.x) # 6
print(getattr(mc,'x')) # 6
delattr(mc,'x')
print(hasattr(mc, 'x')) # False
len()返回对象的长度 及__len__()
print(len('abc')) # 3
print(len([1, 2, 3])) # 3
print(len((1, 2, 3))) # 3
print(len({'a': 1, 'b': 2, 'c': 3})) # 3
class MyClass(object):
def __len__(self):
return 18
# 只有实现了__len__方法的自定义对象,才能使用len(MyClass())就会报错
print(len(MyClass())) # 18
__iter()和__next() 自定义迭代器
"""
自定义迭代器,如果想让for-in语句可以用于自定义类对象的实例对象,必须要实现__iter__()和__next()这两个方法。
for-in语句会首先调用__iter_()返回一个可迭代的对象,然后不断调用__next__()返回下一次迭代的值,直到抛出StopIteration时退出循环
"""
class MyClass(object):
def __init__(self):
self.i = 0
def __iter__(self):
return self
def __next__(self):
if self.i > 5:
raise StopIteration()
else:
self.i += 1
return self.i
for key in MyClass():
print(key) # 1,2,3,4,5,6
__add__()和__radd__() 让两个对象相加,即obj1+obj2
"""
1. + 对应的特殊方法是__add__()和__radd__()
2. - 对应的特殊方法是__sub__()和__rsub__()
3. * 对应的特殊方法是__mul__()和__rmul__()
4. / 对应的特殊方法是__truediv__()和__rtruediv__()
5. // 对应的特殊方法是__floordiv__()和__rfloordiv__()
"""
class MyClass1(object):
def __add__(self, other):
print('add have been called')
return 'x' + other
class MyClass2(object):
def __radd__(self, other):
print('radd have been called')
return other+'y'
# add have been called
# radd have been called
# xy
print(MyClass1()+MyClass2())
__str__() 和__repr()都返回对象的字符串表示
class MyClass(object):
def __str__(self):
return 'x'
def __repr__(self):
return 'y'
print(str(MyClass())) # x
print(repr(MyClass())) # y
# hello
# world
print(str('hello \n world')) # 这是给用户看的
print(repr('hello \n world')) # 'hello \n world', 这是给程序员看的,主要用于调试用的
__new__() 创建实例对象
"""
当使用"类名([实参])"创建实例对象时,python解析器的主要处理过程包括两步:
1. 调用特殊方法__new__()创建实例对象
2. 调用特殊方法__init__()对对象的实例进行初始化
如果__new__()没有定义,就会调用父类中的__new__(),直到找到object中的__new__().
"""
class ParentClass(object):
def __new__(cls):
obj = super().__new__(cls)
print("the object has been created , the id is %s" % id(obj))
return obj
class ChildClass(ParentClass):
def __init__(self):
print("the object has been initialize, the id is %s" % id(self))
# the object has been created, the id is 1897583171176
# the object has been initialize, the id is 1897583171176
c = ChildClass()
# 从上可以看出,它的id是一样的,c这个实例对象实例上是由object中的__new__()方式来创建的。
__del__() 对象被销毁之前,会自动调用__del__()来执行一些额外的清理工作
"""
对象被销毁之前,会自动调用__del__()来执行一些额外的清理工作
当对象的引用计数为0时,对象并不会被立即回收,何时收回并不确定
"""
class MyClass(object):
def __del__(self):
print('the object will be deleted!')
mc = MyClass()
del mc # the object will be deleted!
__getattribute__() 避免指定的属性或方法不存在时抛出AttributeError,可以使用__getattr__()或__getattribute__()
"""
当访问实例对象的属性或方法时,如果指定的属性或方法不存在时,就分抛出AttributeError.
为了避免指定的属性或方法不存时抛出如上错误,可以使用__getattribute__()或者__getattr__()
"""
class MyClass(object):
def __getattribute__(self,name):
if name == "data":
return 18
else:
raise AttributeError("Not Found")
mc = MyClass()
print(mc.data)
__getitem__() ,__setitem__(),delitem__()让实例可以实现类似这样的功能o=obj[key], obj[key]=value或del obj[key]
class MyClass(object):
def __init__(self):
self.data = {}
def __getitem__(self, key):
return self.data[key]
def __setitem__(self, key, value):
self.data[key] = value
def __delitem__(self, key):
del self.data[key]
mc = MyClass()
mc['name'] = 'cong'
mc['age'] = 18
print(mc.data) # {'name': 'cong', 'age': 18}
print(mc.data['name']) # cong
del mc['age']
print(mc.data) # {'name': 'cong'}
__call__() 可以像调用函数一样调用实例
class MyClass(object):
def __call__(self, *args, **kwargs):
print(args, kwargs)
mc = MyClass()
mc() # () {}
mc(1, 2, x=3, y=4) #(1, 2) {'x': 3, 'y': 4}
print(callable(print)) #True
print(callable(mc)) # True
特殊属性__doc__,用于表示类对象的文档字符串
def test():
"""This is a test document string.
This is the detailed information
"""
pass
print(test.__doc__) # This is a test document string.
# Help on function test in module __main__:
# test()
# This is a test document string
# None
print(help(test))
特殊属性__slots__ 可以动态绑定属性和方法
"""
默认情况下,访问实例对象的属性是通过访问特殊属性__dict__来实现的,比如:访问obj.x 其实是访问obj.__dict__['x']
当在对象中定义了特殊属性__slots__后,其实对象就不再创建特殊属性__dict__, #AttributeError: 'MyClass' object has no attribute '__dict__'
__slots__只对当前对象起作用,对其子类是不起作用的,如果子类中也定义了__slots__,它子类动态绑定的内容为子类的slots+父类的slots
"""
from types import MethodType
class MyClass(object):
# 这里可以赋值一个所有元素都是字符串的数组或元组
__slots__ = ("attr1", "do_sth1")
mc = MyClass()
mc.attr1 = 20
# mc.att2 = 23 # AttributeError: 'MyClass' object has no attribute 'att2'
def do_sth1(self):
print('do_sth1 has been called')
mc.do_sth1 = MethodType(do_sth1, mc)
mc.do_sth1() # do_sth1 has been called
print(mc.__dict__)