1 python自省機制
這個是python一大特性,自省就是面向對象的語言所寫的程式在運作時,能知道對象的類型,換句話說就是在運作時能擷取對象的類型,比如通過 type(),dir(),getattr(),hasattr(),isinstance().
a = [1,2,3]
b = {'a':1,'b':2,'c':3}
c = True
print(type(a),type(b),type(c)) # <type 'list'> <type 'dict'> <type 'bool'>
print(isinstance(a,list)) # True
2 python中清單推導式,字典推導式,集合推導式
清單生成式 : 中括号括起來表示清單
(1)[exp for iter_var in iterable if_exp]
#工作過程:
1 疊代iterable中的每個元素,每次疊代都先判斷if_exp表達式結果為真,如果為真則進行下一步,如果為假則進行下一次疊代;
2 把疊代結果指派給iter_var,然後通過exp得到一個新的計算值;
3 最後把所有通過exp得到的計算值以一個新清單的形式傳回。
#相當于這樣的過程:
L = []
for iter_var in iterable:
if_exp:
L.append(exp)
#也可以循環嵌套
(2)[exp for iter_var_A in iterable_A for iter_var_B in iterable_B]
工作過程:
每疊代iterable_A中的一個元素,就把ierable_B中的所有元素都疊代一遍。
#相當于這樣的過程:
L = []
for iter_var_A in iterable_A:
for iter_var_B in iterable_B:
L.append(exp)
字典推導式:大括号括起來,表示為字典
d = {key: value for (key, value) in iterable}
#快速更改字典key,value
mcase = {'a': 10, 'b': 34}
mcase_frequency = {v: k for k, v in mcase.items()}
print(mcase_frequency)
# Output: {10: 'a', 34: 'b'}
集合推導式: 跟清單推導式也是類似的 唯一的差別在于它使用大括号{},表示結果為集合
squared = {x**2 for x in [1, 1, 2]}
print(squared)
# Output: set([1, 4])
3 Python中單下劃線和雙下劃線
>>> class MyClass():
... def __init__(self):
... self.__superprivate = "Hello"
... self._semiprivate = ", world!"
...
>>> mc = MyClass()
>>> print(mc.__superprivate) #私有變量不能直接通路
#print(mc._Myclass__superprivate) 也可以通路,但是不建議這樣通路
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: myClass instance has no attribute '__superprivate'
>>> print(mc._semiprivate)
, world!
>>> print(mc.__dict__)
{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}
-
: 一種約定,Python内部的名字,用來差別其他使用者自定義的命名,以防沖突,就是例如__foo__
,__init__()
__del__()
這些特殊方法__call__()
-
: 一種約定,用來指定變量私有.程式員用來指定私有變量的一種方式.不能用from module import * 導入,其他方面和公有一樣通路;_foo
-
: 意義: 私有變量不能直接通路, 因為解析器用__foo
來代替這個名字,以差別和其他類相同的命名,它無法直接像公有成員一樣随便通路,但是可以通過對象名._類名__xxx這樣的方式可以通路,但是不建議這樣來通路._classname__foo
4 字元串格式化:%和.format
.format在許多方面看起來更便利.對于
%
最煩人的是它無法同時傳遞一個變量和元組.你可能會想下面的代碼不會有什麼問題:
"hi there %s" % name
但是,如果name恰好是(1,2,3),它将會抛出一個TypeError異常.為了保證它總是正确的,你必須這樣做:
"hi there %s" % (name,) # 提供一個單元素的數組而不是一個參數
但是有點醜 .format就沒有這些問題.而且format可以實作模運算符(%)不能做的事
tu = (12,45,22222,103,6)
print('{0} {2} {1} {2} {3} {2} {4} {2}'.format(*tu))
#結果 12 22222 45 22222 103 22222 6 22222
另一點
format()
作為一個函數,可以用作其他函數的參數:
li = [12,45,78,784,2,69,1254,4785,984]
print(map('the number is {}'.format,li))
from datetime import datetime,timedelta
once_upon_a_time = datetime(2010, 7, 1, 12, 0, 0)
delta = timedelta(days=13, hours=8, minutes=20)
gen =(once_upon_a_time + x*delta for x in xrange(20))
print '\n'.join(map('{:%Y-%m-%d %H:%M:%S}'.format, gen))
2010-07-01 12:00:00
2010-07-14 20:20:00
2010-07-28 04:40:00
2010-08-10 13:00:00
2010-08-23 21:20:00
2010-09-06 05:40:00
2010-09-19 14:00:00
2010-10-02 22:20:00
2010-10-16 06:40:00
2010-10-29 15:00:00
2010-11-11 23:20:00
2010-11-25 07:40:00
2010-12-08 16:00:00
2010-12-22 00:20:00
2011-01-04 08:40:00
2011-01-17 17:00:00
2011-01-31 01:20:00
2011-02-13 09:40:00
2011-02-26 18:00:00
2011-03-12 02:20:00
5 疊代器和生成器
将清單生成式中[]改成() 之後資料結構發生改變 ,從清單變為生成器. 在
for...in...
語句中的都是可疊代的:比如lists,strings,files…因為這些可疊代的對象你可以随意的讀取,是以非常友善易用,但是你必須把它們的值放到記憶體裡,當它們有很多值時就會消耗太多的記憶體.
>>> L = [x*x for x in range(10)] #疊代器
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]#清單
>>> g = (x*x for x in range(10)) #生成器
>>> g
<generator object <genexpr> at 0x0000028F8B774200>#生成器對象
通過清單生成式,可以直接建立一個清單。但是受到記憶體限制,清單容量肯定是有限的。而且,建立一個包含百萬元素的清單,不僅是占用很大的記憶體空間,如:我們隻需要通路前面的幾個元素,後面大部分元素所占的空間都是浪費的。是以,沒有必要建立完整的清單(節省大量記憶體空間)。在Python中,我們可以采用生成器:邊循環,邊計算的機制—>generator
生成器的關鍵字yield: 了解
Yield
你必須先了解當你調用函數的時候,函數裡的代碼并沒有運作.函數僅僅傳回生成器對象
>>> def createGenerator():
... mylist = range(3)
... for i in mylist:
... yield i*i
...
>>> mygenerator = createGenerator() # 建立生成器
>>> print(mygenerator) # mygenerator is an object!
<generator object createGenerator at 0xb7555c34>
>>> for i in mygenerator:
... print(i)
0
1
4
當你的函數要傳回一個非常大的集合并且你希望隻讀一次的話,那麼它就非常的友善了.