解析
- 使用雙層循環列表推導式
- 使用
sum(iterable,start=0)
,注意sum
函數帶有一個缺省參數,默認是0- 使用
numpy
中的flatten()
函數- 使用
itertools
中的chain
解析
- 直接使用
b'字符串'的形式
- 使用
字符串.encode()
方法bytes(str,encoding="utf-8")
any
- 原型
any(iterable,/)
,其中下劃線的作用:聲明這個函數前面的參數只能是位置參數- 作用 返回
True
如果bool(elem)
為True
,對於任意的iterable
裡面的elem
來說- 如果是
iterable
是空的,則返回False
all(iterable,/)
- 返回
True
,如果iterable
裡面的所有的elem
的bool(elem)
都返回True
的時候,結果就是True
- 類似
and
的作用注意:
如果iterable
是空,則all
的返回值也是True
什麼是Python的自省機制
python
在運行的時候可以獲取對象的類型和屬性python
是一門強類型的動態語言,強類型是指python很少使用隱式類型轉換,動態語言是指python
在運行的餓時候允許改變對象的類型
dir()
翻譯一下:
dir([object])
-> 字符串列表- 在沒有參數的情況下調用,返回當前作用域中的名稱
- 如果有參數,這個參數必須是一個對象.返回的的是對象的屬性,按照字母順序排序
- 如果對象重寫了
__dir__()
方法,則執行重寫的,否在就調用默認的dir()
方法- 對於模塊對象,返回模塊的屬性
- 對於類對象,返回類的屬性,以及父類的屬性
- 對於其他任何對象,返回對象屬性,類屬性和基類屬性
__dict__
- 如果是實例對象調用,則返回的是實例對象中的屬性(方法不返回),不會返回父類中的屬性
- 如果是類對象調用,則返回的是類對象的屬性和方法,同樣不考慮繼承關系
__name__
並非所有的對象都有名稱,但那些有名稱的對象都將名稱存儲在其__name__
屬性中.注: 名稱是從對象而不是引用該對象的變量中派生的.
模塊擁有名稱,Python解釋器本身被認為是頂級模塊或者主模塊.當以交互的方式運行Python
的時候,局部__name__
變量被賦予值__main__
.同樣滴,當從命令行執行Python模塊,而不是將其導入另一個模塊的時候,其__name__
屬性被賦予值__main__
,而不是該模塊的實際的名稱.這樣,模塊可以查看自身的__name__
值來自行確定它們自己正被如何使用,是作為另一個程序的支持,還是作為從命令行執行的主應用程序.下面這種慣用的語句在Python
中是很常見的:
if __name__ == "main":
# do something test
else:
# do nothing
type
type()
函數有助於我們確定對象是何種類型,它的返回值是類型對象:
id(地址/標識)
blist
和clist
變量引用同一個列表對象.id()
函數給任何給定對象返回唯一的標識符.屬性
對象擁有屬性,並且dir()
函數會返回這些屬性列表.但是有時候,我們只想測試1個或者多個屬性是否存在.如果對象具有我們正在考慮的屬性,那麼通常希望只檢索該屬性.這個任務可以由hasattr()
和getattr()
函數來完成.
可調用
可以調用表示潛在的行為(函數和方法)的對象.可以用callable()
函數來測試對象的可調用性:
實例
在type()
函數提供對象的類型的時候,也可以使用isinstance()
函數測試對象,以確定它是否是某個特定類型或者定制類的實例:
子類
關於類的問題,有一個繼承的概念,有繼承就有父子問題,這是現實生活中很正常的,在變成語言中也是如此.
繼承的關系中,有一個關鍵的概念就是屬性,子類會繼承父類的屬性.那麼如果去判斷一個類是否是另外一個類的子類呢?
可以使用issubclass()
來判斷,注意這裡判斷的時候,自身也是自身的子類.
下面通過一個例子來表述本文中用到的概念和知識:
有時候我們會遇到這樣的需求,需要執行對象的某個方法,或者是對對象的某個字段賦值,而這個方法名和字段名在編碼的時候並不能確定,需要通過參數傳遞字符串的形式輸入.舉個具體的例子: 當我們需要實現一個通用的DBM
框架時,可能需要對數據對象的字段賦值,但我們無法預知用到這個框架的數據對象都有些什麼字段,換言之,我們在寫框架的時候需要通過某種機制訪問未知的屬性.
這個機制被稱為反射(就是由對象自己告訴我們他有哪些屬性),或者是自省(對象自己可以知道自己有哪些屬性),用於實現在運行的時候來獲取對象的信息.
1) 訪問對象的屬性
dir(obj)
調用這個方法可以返回包含
obj
大多數屬性名的列表(會有一些特殊的屬性不包含在內).obj的默認值是當前的模塊對象.
hasattr(obj,attr):
這個方法用於檢查obj是否有一個名為attr的值的屬性,返回一個布爾值.
getattr(obj,attr):
調用這個方法將返回obj中名為attr值的屬性的值,例如如果attr為
bar
,則返回obj.bar
.
setattr(obj,attr,val):
調用這個方法將給
obj
的名為attr
的值屬性賦值為val
.例如如果attr
為bar
,則相當於是obj.bar=val
.
訪問對象的元數據模塊(module)
__doc__:
文檔字符串.如果模塊沒有文檔,這個值是None.__name__:
始終是定義時的模塊名,即使你用了import as為它取了別名,或者是賦值給另一個變量名.__dict__:
包含了模塊裡可用的屬性名-屬性的字典;也就是可以使用模塊名.屬性名訪問的對象.__file__:
包含了該模塊的文件路徑.需要注意的是內建的模塊沒有這個屬性,訪問它會拋出異常.
實例(instance)
實例是指類實例化之後的對象.
__dict__:
包含了可用的屬性名-屬性字典.__class__:
該實例的類對象內建函數和方法(built-in functions and methods)
根據定義,內建(build-in
)模塊是指用C
寫的模塊,可以通過sys
模塊的builtin_module_names
字段查看都有哪些模塊是內建的.這些模塊中的函數和方法可以使用的屬性比較少,不過一般也不需要再代碼中查看它們的信息.
__doc__:
函數或者方法的文檔__name__:
函數或者方法定義時的名字__self__:
僅方法可用,如果是綁定的(bound),則指向調用該方法的類(如果是類方法)或實例(如果是實例方法),否則為None
__module__:
函數或者方法所在的模塊名函數(function)
這裡特指非內建函數.注意,在類中使用def
定義的是方法,方法與函數雖然有相似的行為,但是他們是不同的概念.
__doc__:
函數的文檔,__name__:
函數定義時的函數名__module__:
包含定義該函數的模塊名,同樣注意,是模塊名而不是模塊對象.__dict__:
函數的可用屬性首先記住關鍵記憶:
__somename__
雙下劃線開頭,雙下劃線結束的成員函數.程序員不用調用,Python解釋器在適當的時機或者是特定的情況下自己調用.
自己的理解:
魔法方法其實就是這樣一種方法,是Python語法的一種體現,某種固定的語法在會調用特定的魔法方法.
1) __init__():
對象的創建的時候__init__()會被自動的調用,用來根據傳入的參數來初始化這個實例屬性.
它本身是一個初始化的函數,並不是構造函數.
2) __new__():
- 對象在創建的時候首先是調用
__new__()
方法來創建類並返回這個類的實例.__new__
至少要有一個參數cls
,代表當前類,此參數在實例化的時候由Python
解釋器自動識別__new__
必須要有返回值,返回實例化出來的實例,這點在自己實現__new__
時要特別注意,可以return
父類(通過super(當前類名,cls))__new__
出來實例,或者是直接是object
的__new__
出來的實例.如果__new__創建的是當前類的實例,會自動調用__init__函數,通過return 語句裡面調用的__new__函數的第一個參數是cls來保證是當前類的實例,如果是其他類的類名,那麼實際創建返回的就是其他類的實例,其實就不會調用當前類__init__函數
,也不會嗲用其他類的_init__函數
可以看到第二個並沒有調用__init__
方法,因為__new__
方法沒有創建對象並且返回,所以__init__()
方法對象可以進行實例化.
3) __del__ 函數
將實例化的對象銷毀,即為析構函數.
調用的時機: 當內存被回收的時候自動觸發,這裡內存被回收包括兩種情況:
- 頁面執行完畢回收所有的變量
- 所有的對象被
del
的時候
class Bird(object):
def __init__(self, name):
self.name = name
def fly(self):
print("{} 鳥在飛翔!".format(self.name))
def __del__(self):
print("{} 鳥已經陣亡,被析構了!".format(self.name))
dark = Bird("鴨子")
dark.fly()
結果:
所有的對象被del的時候:
__call__()方法
調用時機:
- 當把對象當做函數調用的時候自動觸發
- 可以模擬函數化操作
- 有點類似於在類中重載了
()
運算符,使得實例對象可以像調用普通的函數那樣,以對象名()
的形式使用.
舉個例子:
如果要想一個類對象,可以被當成一個函數被調用就要給它定義__call__
方法,比如:
可以看到,通過在Student
類中實現了__call__
方法,使得Student
的實例對象變為了可調用對象.
Python中,凡是可以將()
直接應用到自身並執行,都稱為可調用對象.可調用對象包括自定義的函數,Python
內置函數以及本節所講的類實例對象.
對於可調用的對象,實際上名稱()
,可以被理解成 名稱.__call__()
的簡寫.依然以上面的為例子,最後一行代碼其實等價於:
然後自定義函數的例子:
__str__
,__repr__
__str__
- 作用: 返回一個字符串對象,主要讓人友好的辨認的字符串
- 調用時機: 1>
str(obj)
2> format() 3> print()
__repr__:
- 作用: 用來輸出一個對象的官方字符串形式.返回值必須是字符串對象,通常是用來給解釋器看的.
- 調動時機: 1>
repr()
內置函數調用
注意:
如果
__repr__
已經定義,而__str__
未定義,則對象調用__str__ = __repr__
.
下面如果__str__
未定義的時候,則__repr__
會被調用