python進階篇
import 導入模塊
sys.path:獲取指定模塊搜索路徑的字符串集合,可以將寫好的模塊放在得到的某個路徑下,就可以在程序中import時正確找到。
import sys
sys.path.append("")
重新導入模塊
reload(模塊)
==、is
a = [11,22,33]
b = [11,22,33]
>>>a == b
True
>>>a is b
False
>>>a = c
>>>a is c
True
數字在一定范圍內a is b,True,其他范圍False
深拷貝和淺拷貝
a = [11,22,33]
b =a
>>>id(a)==id(b)
True
沒有復制數據,只是把指向的位置復制給它就是淺拷貝
import copy
c = copy.deepcopy(a)
id(a)和id(c)不同,深拷貝
a = [11,22,33]
b = [44,55,66]
c = [a,b]
d = copy.deepcopy(c)
e = copy.copy(c)
a.append(44)
>>>c[0]
[11,22,33,44]
>>>d[0]
[11,22,33]
>>>e[0]
[11,22,33,44]
**copy.copy()列表后,id 也不同,但是會持續拷貝 **
改為元組后,copy.copy(),id相同,元組不可變類型,直接淺拷貝
copy.copy()根據可變不可變類型,功能不同
十進制,二進制,八進制,十六進制之間的轉換

私有化
-
xx:公有變量
-
_x:from somemodule import * 禁止導入,類對象和子類可以訪問
-
__xx:雙前置下划線,避免與子類中的屬性命名沖突,無法在外部直接訪問
-
___xx___:雙前后下划線,對象或屬性
-
xx_:單后置下划線,用於避免與python關鍵字的沖突
1.私有屬性添加getter和setter方法
class Money(object): def __init__(self): self.__money = 0 def getMoney(self): return self.__money def setMoney(self,value): if isinstance(value,int): self.__money = value else: print("error:不是整型數字")
2.使用property升級getter和setter方法
class Money(object): def __init__(self): self.__money = 0 def getMoney(self): return self.__money def setMoney(self,value): if isinstance(value,int): self.__money = value else: print("error:不是整型數字") money = property(getMoney,setMoney)注意:
-
t.num到底是調用getNum()還是setNum(),要根據實際場景來判斷;
-
如果是給t.num賦值,那么一定是調用setNum()
-
如果是獲取t.num的值,那么就一定調用getNum()
-
property的作用:相當於把方法進行了封裝,開發者在對屬性設置數據的時候更方便
class Money(object): def __init__(self): self.__money = 0 @property def money(self): return self.__money @money.setter def money(self,value): if isinstance(value,int): self.__money = value else: print("error:不是整型數字")
迭代器
1.可迭代對象
直接作用於for循環的數據類型有以下幾種:
一種是集合數據類型,如list,tuple,dict,set,str等;
一種是generator,包括生成器和帶yield的generator function。
這些可以直接作用於for循環的對象統稱為可迭代對象:lterable。
2.判斷是否可以迭代
可以使用isinstance()判斷一個對象是否是lterable:
from collections import Iterable isinstance("abc",Iterable) >>>True
3.迭代器
可以被next()函數調用並不斷返回下一值的對象成為迭代器:Iterator
from collections import Iterator
isinstance([],Iterator)
>>>False
isinstance((x for x in range(10)),Iterator)
>>>True
4.iter()函數
生成器都是Iterator對象,但list、dict、str雖然是Iterable,卻不是Iterator。
把list、dict、str等Iterable變成Iterator可以使用iter()函數:
isinstance(iter([]),Iterator)
>>>True
閉包
#在函數內部再定義一個函數,並且這個函數用到了外邊函數的變量,那么將這個函數以及用到的一些變量稱之為閉包 def test(number): print("----1------") def test_in(number2): print("------2----") print(number-number2) print("-----3-----") return test_in ret = test(100) ret(1) \>>>----1------ -----3----- ------2---- 99 def test(a,b): def test_in(x): print(a*x+b) return test_in line1 = test(1,1) line1(0) line2 = test(10,4) line2(0) line1(0)
裝飾器
def w1(func):
def inner():
print("----正在驗證權限------")
func()
return inner
def f1():
print("----f1-----")
def f2():
print("----f2-----")
innerFunc = w1(f1)
innerFunc()
f1 賦值地址,f1()調用函數
def w1(func):
def inner():
print("----正在驗證權限------")
func()
return inner
def f1():
print("----f1-----")
def f2():
print("----f2-----")
f1 = w1(f1)
f1()
@w1等價於w1(f1)
def w1(func):
def inner():
print("----正在驗證權限------")
func()
return inner
@w1
def f1():
print("----f1-----")
@w1
def f2():
print("----f2-----")
f1()
f2()
多個裝飾器
def makeBold(fn):
def wrapped():
print("----1------")
return "" + fn() + ""
return wrapped
def makeItalic(fn):
def wrapped():
print("----2------")
return "" + fn() +""
return wrapped
@makeBold#只要python解釋器執行到了這個代碼,那么就會自動進行裝飾,而不是等到調用才裝飾的
@makeItalic
def test3():
print("--------3-----")
return "hello world-3"
ret = test3()
print(ret)
>>>----1------
----2------
--------3-----
hello world-3
從上往下執行,從下往上裝飾
def w1(func):
print("----正在裝飾1-----")
def inner():
print("------正在驗證權限1-----")
def w2(func):
print("---- 正在裝飾2-----")
def inner():
print("----正在驗證權限2----")
func()
return inner()
@w1
@w2
def f1():
print("----f1----")
f1() #在調用f1之前,已經進行裝飾了
>>>---- 正在裝飾2-----
----正在裝飾1-----
------正在驗證權限1-----
----正在驗證權限2----
----f1----
裝飾器對有參數,無參數函數進行裝飾
def func(functionName): print("----func---1---") def fun_in(*args,**kwargs):#定義不定長參數 print("---func_in---1---") functionName(*args,**kwargs) print("---func_in---2---") print("---func---2---") return func_in @func def test1(a,b,c): print("----test-a=%d,b=%d,c=%d---"%(a,b,c)) @func def test2(a,b,c,d): print("----test-a=%d,b=%d,c=%d,d=%d---"%(a,b,c,d)) test1(11,22,33) test2(44,55,66,77) \>>>----func---1--- ---func---2--- ---func---1--- ---func---2--- ---func_in---1--- ----test-a=11,b=22,c=33--- ---func_in---2--- ---func_in---1--- ----test-a=44,b=55,c=66,d=77--- ---func_in---2---裝飾器對帶有返回值的參數進行裝飾
def func(functionName): print("---func---1---") def func_in(): print("---func_in---1---") ret = functionName()#保存返回來的haha print("---func_in---2---") return ret #把haha返回到調用處 print("---func---2---") @func def test(): print("----test----") return "haha" ret = test() print("test return value is %s"%ret) 帶有參數的裝飾器 def func_arg(arg): def func(functionName): def func_in(): print("---記錄日志-arg=%s--"%arg) if arg =="heihei": functionName() functionName() else: functionName() return func_in() return func @func_arg("heihei")#帶有參數的裝飾器,能夠起到在運行時,有不同的功能 def test(): print("--test--") @func_arg("haha") def test2(): print("--test2--") test() test2()
作用域
LEGB規則
locals -> enclosing function -> globals -> builtings
locals:當前所在命名空間
enclosing function:外部嵌套函數的命名空間(閉包中常見)
globals:全局變量
builtings:內嵌
動態添加屬性和方法
添加屬性 類/實例.屬性 = XX
添加方法 不能按上面方法,
import types.MethodType
綁定的對象.函數名() = types.MethodType(函數名,綁定的對象)
_slots_
為了達到限制的目的,Python允許在定義class的時候,定義一個特殊的__slots__變量來限制class實例能添加的屬性:
>>>class Person(object): __slots__ = ("name","age") >>>P = Person() >>>P.name = "老王" >>>P.age = 20 #添加其他屬性會報錯生成器
一邊循環一邊計算
創建生成器方法
1.把列表生成式的[]改成(),通過next函數獲取生成器的下一個返回值
def creatNum(): print("-----start-----") a,b = 0,1 for i in range(5): print("----1----") yield b #程序停下來,把yield后面的值返回 print("----2----") a,b = b,a+b print("----3----") print("----stop----") \>>>a = creatNum() \>>>a <generator object creatNum at 0x7f42d27de7d8> \>>>next(a) -----start----- ----1---- 1 \>>>next(a)#等價於a.__next__() ----2---- ----3---- ----1---- 1def test(): i = 0 while i<5: temp = yield i print(temp) i+=1 \>>>t = test() \>>>t.__next__() [out] 0 \>>>t.__next__() None [out] 1 \>>>t.__next__() None [out] 2 \>>>t.send("haha") haha [out] 3類當作裝飾器
定義一個__call__方法,類就可以直接調用
-
class Test(object):
def __init__(self,func):
print("---初始化---")
print("func name is %s"%func.__name__)
self.__func = func
def __call__(self):
print("---裝飾器中的功能---")
self.__func()
@Test
def test():#當用Test來裝作裝飾器對test函數進行裝飾的時候,首先會創建一個Test的實例對象,func指向test(),func.__name__函數名
print("---test---")
test()
元類
類也是一個對象
使用type創建類
type(類名,由父類名稱組成的元組(針對繼承的情況可以為空),包含屬性的字典)
Person = type("Person",(),{"num":0})
p1 = Person()
\>>>p1.num
0
def printNum(self):
print("---num-%d---"%self.num)
\>>>Test3 = type("Test3",(),{"printNum":printnum})
t1 = Test3()
t1.num = 100
t1.printNum()
---num-100---
__metaclass__屬性
def upper_attr(future_class_name,future_class_parents,future_class_attr):
#遍歷屬性字典,把不是__開頭的屬性名字變為大寫
newAttr = {}
for name,value in future_class_attr.items():
if not name.startswith("__"):
newAttr[name.upper()] = value
#調用type來創建一個類
return type(future_class_name,future_class_parents,newAttr)
class Foo(object,metaclass = upper_attr):
#設置Foo類的元類為upper_attr
bar = "bip"
print(hasattr(Foo,'bar'))
print(hasattr(Foo,'BAR'))
f = Foo()
print(f.BAR)
垃圾回收
1.小整數對象池
[-5,257)這些整數對象是提前建立好的,不會被垃圾回收。在一個python程序中,所有位於這個范圍內的整數使用的都是同一個對象
2.大整數對象池
3.intern機制
- 小整數共用對象,常駐內存
- 單個字符共用對象,常駐內存
- 單個單詞,不可修改,默認開啟intern機制,共用對象,引用計數為0,則銷毀
Garbage collection(GC垃圾回收)
python采用的是引用計數機制為主,標記-清除和分代收集兩種機制為輔的 策略
引用計數機制的優點:
- 簡單
- 實用性:一旦沒有引用,內存就直接釋放了。處理回收內存的時間分攤到了平時
缺點:
-
維護引用計數消耗資源
-
循環引用
list1 = [] list2 = [] list1.append(list2) list2.append(list1)相互引用,list1與list2的引用計數也仍然為1,所占用的內存永遠無法被回收。
鏈表引用計數,分代收集
1.引用計數+1的情況
- 對象被創建,例如a=23
- 對象被引用,例如b =a
- 對象被作為參數,傳入到一個函數中,例如func(a)
- 對象作為一個元素,存儲在容器中,例如list1=[a,a]
2.引用計數-1的情況
- 對象的別名被顯式銷毀,例如del a
- 對象的別名被賦予新的對象,例如a=24
- 一個對象離開他的作用域,例如func函數執行完畢時,func函數中的局部變量(全局變量不會)
- 對象所在的容器被銷毀,或從容器中刪除對象
3.查看一個對象的引用計數
import sys a = "hello world" sys.getrefcount(a) \>>>2import gc#gc默認運行 gc.disable()#關閉gc gc.collect()#手動調用collect內建屬性
常用專有屬性 說明 觸法方式 _init_ 構造初始化函數 創建實例后,賦值時使用,在__new__后 _new_ 生成實例所需屬性 創建實例時 _class_ 實例所在的類 實例._class_ _str_ 實例字符串表示,可讀性 print(類屬性),如沒實現,使用repr結果 _repr_ 實例字符串表示,准確性 類實例 回車 或者print(repr(類實例)) _del_ 析構 del刪除實例 _dict_ 實例自定義屬性 vars(實例._dict_) _doc_ 類文檔,子類不能繼承 help(類或實例) _getattribute_ 屬性訪問攔截器 訪問實例屬性時 _base_ 類的所有父類構成元素 類名._bases_ 內建函數
map函數
map(function,sequence[,sequence,...]) -> list
- function:是一個函數
- sequence:是一個或多個序列,取決於function需要幾個參數
- 返回值是一個list
#函數需要一個參數 map(lambda x:x*x,[1,2,3]) # 結果為:[1,4,9] #函數需要兩個參數 map(lambda x, y: x+y,[1,2,3],[4,5,6]) #結果為:[5,7,9] def f1(x, y): return (x,y) l1 =[0,1,2,3,4,5,6] l2 =['Sun','M','T','W','T','F','S'] l3 =map(f1,l1,l2) print(list(l3)) #結果為:[(0,'Sun'),(1,'M'),(2,'T'),(3,'W'),(4,'T'),(5,'F'),(6,'S')]filter函數
對指定對象執行過濾
filter函數會對序列參數sequence中的每個元素調用function函數,最后返回的結果包含調用結果為Ture的元素。
返回值的類型和參數sequence的類型相同
filter(lambda x: x%2,[1,2,3,4]) [1,3] filter(None,"she") 'she'reduce函數
reduce依次從sequence中取一個元素,和上一次調用function的結果做參數再次調用function。第一次調用function時,如果提供initial參數,會以sequence中的第一個元素和initial作為參數調用function,否則會以序列sequence中的前兩個元素做參數調用function.注意function函數不能為None。
reduce(lambda x, y: x+y,[1,2,3,4]) 10 reduce(lambda x,y:x+y,[1,2,3,4],5) 15 reduce(lambda x, y:x+y,['aa','bb','cc'],'dd') 'ddaabbcc' python3里面reduce函數要先引入:from functools import reducesorted函數
a = [55,22,77,99] a.sort() \>>>a [22,55,77,99] a.sort(reverse=Ture) \>>>a [99,77,55,22] sorted([1,5,4,2]) \>>>[1,2,4,5] sorted([1,5,4,2],reverse=1) \>>>[5,4,2,1]集合set
a=[11,55,44,22,11,11] b = set(a) \>>>b {11,55,44,22} \>>>a=list(b) \>>>a [11,55,44,22] a = "abcdef" b = set(a) \>>>b {'a','b','c','d','e','f'} A="bdfhuy" B = set(A) \>>>B {'b','d','f','h','u','y'} \>>>b&B {'b','d','f'} \>>>b|B {'a','b','c','d','e','f,'h','u','y'} \>>>b-B {'a','c','e'} \>>>b^B {'a','c','e','h','u','y'}functools
partial函數
import functools def showarg(*args,**kw): print(arg) print(kw) p1=functools.partial(showarg,1,2,3) p1() p1(4,5,6) p1(a='python',b='itcast') \>>>(1,2,3) {} (1,2,3,4,5,6) {} (1,2,3) {'a':'python','b':'itcast'}wraps函數
使用裝飾器時,被裝飾后的函數其實已經是另外一個函數(函數名等函數屬性會發生改變,functools包中提供了叫warps的裝飾器來消除這樣的副作用。
import functools
def note(func):
"note function"
@functools.wraps(func)
def wrapper():
"wrapper function"
print('note something')
return func()
return wrapper
@note
def test():
"test function"
print('I am test')
test()
print(test.__doc__)
模塊
hashlib加密算法
import hashlib
m = hashlib.md5()#創建hash對象,md5
print m
m.update('itcast')#更新哈希對象以字符串參數
print(m.hexdigest())#返回十六進制數字字符串
