系列
- Python: 學習系列之一:Python能做什麼
- Python: 學習系列之二:基礎介紹(int/float/string/range/list/tuple/dict/set)
- Python: 學習系列之三:基礎介紹二
- Python: 學習系列之四:有趣的經典數學問題
- Python: 學習系列之五:類、繼承、多態、封裝
- Python: 學習系列之六:對象的內置函數及類對象的特殊方法
- Python: 學習系列之七:模塊、PIPY及Anaconda
- Python: 學習系列之八:異常的處理
- Python: 學習系列之九:文件讀寫
- Python: 學習系列之十:函數
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__)