淺拷貝:html
a = [1,2,3,4] b = a print(id(a)) #2540558597256 print(id(b)) #2540558597256 a.append(5) print(a) #[1, 2, 3, 4, 5] print(b) #[1, 2, 3, 4, 5]
深拷貝:python
b = copy.deepcopy(a)算法
b獲得的內容與a的內容徹底同樣,地址不同。編程
就算a中有對象引用,b中對應的引用的對象依然是內容同樣,地址不同。json
遞歸拷貝緩存
注意:
若是是一個不可變對象(內部存儲仍是不可變對象),深拷貝的結果 = 淺拷貝,地址同樣多線程
copy.copy閉包
import copy a = [1,2,3,4] #至關於深拷貝 b = copy.copy(a) print(id(a)) print(id(b)) a.append(5) print(a) print(b) print('*'*50) a = (1,2,3,4) #至關於淺拷貝 b = copy.copy(a) print(id(a)) print(id(b)) ---------------------------- a = [11,22,33] b = [44,55,66] c = [a,b] d = copy.copy(c) print(id(c)) print(id(d)) print(c) print(d) print('*'*50) a.append(120) #c[0].append(120) print(c) print(d) print('*'*50) a = [11,22,33] b = [44,55,66] c = (a,b) d = copy.copy(c) print(id(c)) print(id(d)) print(c) print(d) print('*'*50) a.append(120) #c[0].append(120) print(c) print(d)
私有的內容,對外不能直接訪問。 若是想對外訪問,須要提供能夠訪問的方法,好比這裏的getMoney,setMoney 調用的時候比較麻煩。 能不能像操做屬性同樣呢? 屬性名 = property(get,set)
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:不是整型數字") m = Money() print(m.getMoney()) m.setMoney(10) print(m.getMoney())
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) m.money = 120 #至關於上面的m.setMoney(120) print(m.money) #至關於上面的m.getMoney #或者是 print(Money.money)
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:不是整型數字") m = Money() print(m.money) m.money = 120 print(m.money)
若是列表元素能夠按照某種算法推算出來,那咱們是否能夠在循環的過程當中不斷推算出後續的元素呢?這樣就沒必要建立完整的list,從而節省大量的空間。在Python中,這種一邊循環一邊計算的機制,稱爲生成器:generator。app
要建立一個生成器,有不少種方法。第一種方法很簡單,只要把一個列表生成式的 [ ] 改爲 ( )dom
#列表生成式 ls = [x for x in range(100)] print(ls)
#生成器 ge = (x**2 for x in range(1000)) print(ge) print(type(ge)) i = 0 while i<19: next(ge) i+=1 print(next(ge))
總結
生成器保存的是算法,每次調用 next(G) ,就計算出 G 的下一個元素的值,直到計算到最後一個元素,沒有更多的元素時,拋出 StopIteration 的異常。固然,這種不斷調用 next() 實在是太變態了,正確的方法是使用 for 循環,由於生成器也是可迭代對象。因此,咱們建立了一個生成器後,基本上永遠不會調用 next() ,而是經過 for 循環來迭代它,而且不須要關心 StopIteration 異常。
yield 值
def fib(times): print('0....') n = 0 a,b = 0,1 while n<times: print('1....') yield b print('2....') a,b = b,a+b n+=1 print('3....') ge = fib(5) print(ge) print('*'*50) m = 0 while m<5: print(next(ge)) m+=1
第一種和第二種,一旦生成器肯定,算法不能改變。
這裏的例子,定義了變量(temp),可使用send發送參數,發給這裏變量。
根據這個變量的值的不一樣,能夠改變算法的邏輯。
因此,這種寫法的做用:在運行過程當中,能夠改變算法
def gen(): i = 0 while i<1000: temp = yield i if temp==True: #邏輯代碼 print('執行A計劃') i+1 else: #邏輯代碼 print('執行B計劃') i+=2 myGenerator = gen() ret = next(myGenerator) print(ret) #一、爲當前中止的代碼的左側變量賦值 #二、生成器往下走一個行,返回yield值 ret = myGenerator.send(True) print(ret) ret = myGenerator.send(False) print(ret)
import time def test1(): while True: print("--王者榮耀--") #time.sleep(2) yield None def test2(): while True: print("--music--") yield None def main(): t1 = test1() t2 = test2() while True: t1.__next__() t2.__next__() main()
總結
生成器的特色:
迭代是訪問集合元素的一種方式。迭代器是一個能夠記住遍歷的位置的對象。迭代器對象從集合的第一個元素開始訪問,直到全部的元素被訪問完結束。迭代器只能往前不會後退。
以直接做用於 for 循環的數據類型有如下幾種:
這些能夠直接做用於 for 循環的對象統稱爲可迭代對象: Iterable 。
isinstance(對象,Iterable)
若是結果爲True
只是表示,這些對象以使用for循環迭代遍歷,可使用next
import collections ge = (x for x in range(10)) print(isinstance(ge,collections.Iterable)) #True print(isinstance(ge,collections.Iterator)) #True print(next(ge)) #0 print('************************華麗的分割線************************') ls = [x for x in range(10)] print(isinstance(ls,collections.Iterable)) #True print(isinstance(ls,collections.Iterator)) #False for i in ls: print(i) #0-9的數
ls = [33,4,5,6,7,8] it=iter(ls) for i in range(len(ls)): print(next(it)) #33-8的數
總結
def test1(): print("--- in test1 func----") #調用函數 test1() #此是ret引用函數 ret = test1 print(id(ret)) #18779264 print(id(test1)) #18779264,地址都同樣,說明指向同一個內存地址 #經過引用調用函數 ret() #--- in test1 func----
def outer(num): print('outer...') def inner(): print('num=%s'%num) return inner ret = outer(100) #outer... ret() #num=100 ret() #num=100
def line_conf(a, b): def line(x): return a*x + b return line line1 = line_conf(2,3) print(line1(10)) #23 line2 = line_conf(3,4) print(line2(10)) #34
閉包的優缺點
def outer(func): print('outer...') def inner(): print('inner...') func() return inner def save(): print('save...') ret = outer(save) #outer ret() #inner... save...
def login(func): def inner(): name = input('輸入用戶名:') pwd = input('輸入密碼:') if name=='laowang' and pwd=='123': func() else: print('趕忙去登陸。。。。。。') return inner @login def save(): print('save...') save()
def makeBold(fn): print('makeBold...') def wrapped(): return "--1--" + fn() + "--1--" return wrapped def makeItalic(fn): print('makeItalic...') def wrapped(): return "--2--" + fn() + "--2--" return wrapped @makeBold @makeItalic def test(): return "hello world-test" print(test()) #結果 #makeItalic... #makeBold... #--1----2--hello world-test--2----1--
from time import ctime, sleep def timefun(func): def wrappedfunc(): print("%s called at %s"%(func.__name__, ctime())) func() return wrappedfunc @timefun def foo(): print("I am foo") foo() #foo called at Thu Jul 20 16:03:59 2017 #I am foo sleep(2) foo()
foo = timefun(foo) #foo先做爲參數賦值給func後,foo接收指向timefun返回的wrappedfunc foo() #調用foo(),即等價調用wrappedfunc() #內部函數wrappedfunc被引用,因此外部函數的func變量(自由變量)並無釋放 #func裏保存的是原foo函數對象
def timefun(func): def wrappedfunc(a, b): print("%s called at %s"%(func.__name__, ctime())) print(a, b) func(a, b) return wrappedfunc @timefun def foo(a, b): print(a+b) foo(3,5) #foo called at Thu Jul 20 16:07:48 2017 #3 5 #8
from time import ctime, sleep def timefun(func): def wrappedfunc(*args, **kwargs): print(args) print(kwargs) print("%s called at %s"%(func.__name__, ctime())) func(*args,**kwargs) return wrappedfunc @timefun def foo(a, b, c,num): print(a+b+c) print(num) foo(3,5,7,num=123) #(3, 5, 7) #{'num': 123} #foo called at Thu Jul 20 16:11:06 2017 #15 #123
from time import ctime, sleep def timefun_arg(pre="hello"): def timefun(func): def wrappedfunc(): print("%s called at %s %s"%(func.__name__, ctime(), pre)) return func() return wrappedfunc return timefun @timefun_arg("wangcai") def foo(): print("I am foo") @timefun_arg("python") def too(): print("I am too") foo() #foo called at Thu Jul 20 16:23:48 2017 wangcai #I am foo print('************************華麗的分割線************************') too() #too called at Thu Jul 20 16:23:48 2017 python #I am too
總結:
通常狀況下爲了讓裝飾器更通用,能夠有return
def haha(x): def outer(func): def inner(): if x%2==0: return func()+'八' else: return '八'+func() return inner return outer @haha(1) def laowang(): return '老王' print(laowang()) #八老王
class Test(object): def __init__(self, func): print("---初始化---") print("func name is %s"%func.__name__) self.__func = func def __call__(self): print("---裝飾器中的功能---") self.__func() #說明: #1. 當用Test來裝做裝飾器對test函數進行裝飾的時候,首先會建立Test的實例對象 # 而且會把test這個函數名當作參數傳遞到__init__方法中 # 即在__init__方法中的func變量指向了test函數體 # #2. test函數至關於指向了用Test建立出來的實例對象 # #3. 當在使用test()進行調用時,就至關於讓這個對象(),所以會調用這個對象的__call__方法 # #4. 爲了可以在__call__方法中調用原來test指向的函數體,因此在__init__方法中就須要一個實例屬性來保存這個函數體的引用 # 因此纔有了self.__func = func這句代碼,從而在調用__call__方法中可以調用到test以前的函數體 @Test def test(): print("----test---") test() showpy()#若是把這句話註釋,從新運行程序,依然會看到"--初始化--" 運行結果以下: ---初始化--- func name is test ---裝飾器中的功能--- ----test---
動態編程語言是高級程序設計語言的一個類別,在計算機科學領域已被普遍應用。它是一類 在運行時能夠改變其結構的語言 :例如新的函數、對象、甚至代碼能夠被引進,已有的函數能夠被刪除或是其餘結構上的變化。動態語言目前很是具備活力。例如JavaScript即是一個動態語言,除此以外如 PHP 、 Ruby 、 Python 等也都屬於動態語言,而 C 、 C++ 等語言則不屬於動態語言。----來自維基百科
class mv_hero: def __init__(self,name,HP,MP): self.name = name self.HP = HP self.MP = MP #調用,實例化 gtx = mv_hero('cjr',10,10) print(gtx.name) #cjr #添加一個實例屬性 gtx.XP = 100 print(gtx.XP) #100 #添加一個類屬性 mv_hero.xx = 99 #gtx.xx = 111 print(gtx.xx) #99 #定義一個類方法 @classmethod def atteck(cls): cls.num = 100 #定義一個靜態方法 @staticmethod def test_hero(): print('--test_hero--') #給mv_hero類綁定類方法 mv_hero.atteck = atteck #調用剛纔綁定的類方法 mv_hero.atteck() print(mv_hero.num) #100 #給mv_hero類綁定靜態方法 mv_hero.test_hero = test_hero #調用剛纔綁定的靜態方法 mv_hero.test_hero() #--test_hero-- import types #定義一個實例方法 def fly(self, speed): print("%s在移動, 速度是 %s"%(self.name, speed)) #給mv_hero中的對象綁定實例方法 gtx.fly = types.MethodType(fly, gtx) #調用剛纔的實例方法 gtx.fly(180) #cjr在移動, 速度是 180
如今回到咱們的大主題上來,到底是爲何你會去使用這樣一種容易出錯且晦澀的特性?好吧,通常來講,你根本就用不上它!
''' 使用type建立類 type的第3個參數 一、字符串 類名 二、元組 父類 三、字典 類屬性 ''' ''' class Test: pass ''' Test = type('Test',(),{}) print(Test) Test = type('Test',(),{'name':'老王','age':10}) print(Test.name) class Fu: def fu(self): print('fu...') Zi = type('Zi',(Fu,),{}) print(Zi.__mro__) print('***************************************華麗的分割線***************************************') def haha(self): print('haha...') def __init__(self,num): print('self...') self.num = num @classmethod def hehe(cls): print('hehe...') Test = type('Test',(),{'name':'老王','age':10,'haha':haha,'hehe':hehe,'__init__':__init__}) t = Test(110) t.haha() Test.hehe()
python建立9個」HelloWorld」對象,讓他只佔用一個」HelloWorld」所佔的內存空間,python中有這樣一個機制——intern機制,靠引用計數去維護什麼時候釋放。
字符串(含有空格),不可修改,沒開啓intern機制,不共用對象,引用計數爲0,銷燬。
總結
python採用的是引用計數機制爲主,標記-清除和分代收集兩種機制爲輔的策略
map(function, sequence[, sequence, ...]) -> list ·function:是一個函數 ·sequence:是一個或多個序列,取決於function須要幾個參數 ·返回值是一個列表 參數序列中的每個元素分別調用function函數 返回包含每次function函數返回值的list。 注意:先轉成list才能print
>>>def square(x) : # 計算平方數 ... return x ** 2 >>> map(square, [1,2,3,4,5]) # 計算列表和:1+2+3+4+5 [1, 4, 9, 16, 25] >>> map(lambda x: x ** 2, [1, 2, 3, 4, 5]) # 使用 lambda 匿名函數 [1, 4, 9, 16, 25] # 提供了兩個列表,對相同位置的列表數據進行相加 >>> map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10]) [3, 7, 11, 15, 19]
range(start, stop[, step]) -> list of integers ·start:計數從start開始。默認是從0開始。例如range(5)等價於range(0,5); ·stop:到stop結束,但不包括stop.例如:range(0,5) 是[0, 1, 2, 3, 4]沒有5 ·step:每次跳躍的間距,默認爲1。例如:range(0,5) 等價於range(0, 5, 1) python2中range返回列表,python3中range返回一個迭代值。若是想獲得列表,可經過list函數
filter(function or None, sequence) -> list, tuple, or string ·function:接受一個參數,返回布爾值True或False ·sequence:序列能夠是str,tuple,list ·返回值是一個列表
過濾出列表中的全部奇數: def is_odd(n): return n % 2 == 1 newlist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) print(newlist) 輸出結果 : [1, 3, 5, 7, 9]
sorted()
sort 與 sorted 區別:
sort 是應用在 list 上的方法,sorted 能夠對全部可迭代的對象進行排序操做。
list 的 sort 方法返回的是對已經存在的列表進行操做,而內建函數 sorted 方法返回的是一個新的 list,而不是在原來的基礎上進行的操做。
sorted(iterable, key=None, reverse=False) --> new sorted list reverse默認值爲False,升序排序
>>>a = [5,7,6,3,4,1,2] >>> b = sorted(a) # 保留原列表 >>> a [5, 7, 6, 3, 4, 1, 2] >>> b [1, 2, 3, 4, 5, 6, 7] >>> L=[('b',2),('a',1),('c',3),('d',4)] >>> sorted(L, cmp=lambda x,y:cmp(x[1],y[1])) # 利用cmp函數 [('a', 1), ('b', 2), ('c', 3), ('d', 4)] >>> sorted(L, key=lambda x:x[1]) # 利用key [('a', 1), ('b', 2), ('c', 3), ('d', 4)] >>> students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)] >>> sorted(students, key=lambda s: s[2]) # 按年齡排序 [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] >>> sorted(students, key=lambda s: s[2], reverse=True) # 按降序 [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
reduce(function, sequence[, initial]) -> value ·function:該函數有兩個參數 ·sequence:序列能夠是str,tuple,list ·initial:固定初始值 reduce依次從sequence中取一個元素, 和上一次調用function的結果作參數再次調用function。 第一次調用function時,若是提供initial參數, 會以sequence中的第一個元素和initial做爲參數調用function, 不然會以序列sequence中的前兩個元素作參數調用function。 注意function函數不能爲None。
在Python3裏,reduce函數已經被從全局名字空間裏移除了,它如今被放置在fucntools模塊裏用的話要先引入:from functools import reduce
>>>def add(x, y) : # 兩數相加 ... return x + y ... >>> reduce(add, [1,2,3,4,5]) # 計算列表和:1+2+3+4+5 15 >>> reduce(lambda x, y: x+y, [1,2,3,4,5]) # 使用 lambda 匿名函數 15
def f(x,y): print('x=%s,y=%s'%(x,y)) return x+y #ret = functools.reduce(lambda x, y: x+y, ['a','b','c','d'],'o') ret = functools.reduce(f, ['a','b','c','d'],'o') 運行結果: x=o,y=a x=oa,y=b x=oab,y=c x=oabc,y=d
functools 是python2.5被引人的,一些工具函數放在此包裏。
知道有這麼個東西
標準庫 | 說明 |
---|---|
builtins | 內建函數默認加載 |
sys | 操做系統藉口 |
functooks | 經常使用的工具 |
json | 編碼和解碼JSON對象 |
logging | 記錄日誌、調試 |
multiprocessing | 多進程 |
threading | 多線程 |
copy | 拷貝 |
time | 時間 |
datetime | 日期和時間 |
calendar | 日曆 |
hashlib | 加密算法 |
random | 生成隨機數 |
re | 字符串正則匹配 |
socket | 標準的BSD Sockets API |
shutil | 文件和目錄管理 |
glob | 基於文件通配符搜索 |
更多標準庫
http://python.usyiyi.cn/translate/python_352/library/index.html
在pycharm裏,Ctrl+Alt+L自動排版,排版的時候注意看一看就記住了
pycharm
步驟: