語言排行榜
https://www.tiobe.com/tiobe-index/
編碼格式ascii/unicode/utf-8
1、unicode
In [11]: name=u"范特西" In [12]: name Out[12]: u'\u8303\u7279\u897f' In [13]: print name 范特西 In [14]: type(name) Out[14]: unicode
2、unicode轉換爲utf-8
In [15]: name.encode('utf-8') Out[15]: '\xe8\x8c\x83\xe7\x89\xb9\xe8\xa5\xbf' In [16]: name_utf8=name.encode('utf-8') In [17]: name_utf8 Out[17]: '\xe8\x8c\x83\xe7\x89\xb9\xe8\xa5\xbf' In [18]: len(name_utf8) Out[18]: 9 In [21]: print '\xe8\x8c\x83' 範 In [22]: print '\xe7\x89\xb9' 特 In [23]: print '\xe8\xa5\xbf' 西
注意:ascii可以作爲unicode的子集;內存爲unicode編碼統一處理;爲了節省硬盤空間,將unicode轉換爲utf-8;如果有中文需要 #_*_ coding:utf-8 _*_
In [25]: name_utf8='葉惠美' In [26]: name_utf8 Out[26]: '\xe5\x8f\xb6\xe6\x83\xa0\xe7\xbe\x8e' In [27]: name_unicode=u'葉惠美' In [28]: name_unicode Out[28]: u'\u53f6\u60e0\u7f8e' In [29]: name_unicode.encode('utf-8') Out[29]: '\xe5\x8f\xb6\xe6\x83\xa0\xe7\xbe\x8e' In [30]: name_utf8.decode('utf-8') Out[30]: u'\u53f6\u60e0\u7f8e'
命令執行狀態結果與執行結果
In [31]: import os In [33]: cur_dir=os.system('pwd') ---執行狀態結果 /root In [34]: print cur_dir 0 In [35]: dir=os.popen('pwd').read() --- 執行結果 In [36]: dir Out[36]: '/root\n' In [37]: import commands In [38]: dir=commands.getstatusoutput('pwd') --- 執行結果 In [39]: dir Out[39]: (0, '/root')
id及type(變量引用數據的id,類型,值)
>>> num=1 >>> id(num) 37322512 >>> name="tom" >>> id(name) 41956248 >>> >>> type(num) <type 'int'> >>> type(name) <type 'str'> >>>
實例被創建後,對象的id和類型無法修改;
值可以修改,爲可變對象;不可修改,爲不可變對象;
某個對象包含其他對象的引用,則稱爲容器;列表
數據的屬性和方法
屬性:內部可用的變量
方法:內部可用的函數,()運算符
對象引用:所有數據存放爲內存對象;所有變量是指向內存的引用;變量名與數據單獨存放;
name="tom" name -> tom
name="jerry" name -> jerry tom (不被引用時將自動刪除,指針計數)
= 將變量名與數據進行綁定;如果存在,則直接綁定,否則先創建再綁定;
>>> test="tom" >>> id(test) 41956248 >>> name 'tom' >>> id(name) 41956248 >>>
變量區分大小寫,只能包含字母、數字、下劃線
命名規範:
1、以單一下劃線開頭(_x)不會被from module import * 導入
2、前後有雙下劃線(__x__)爲系統變量,對python解釋器有特殊意義
3、以兩個下劃線開頭(__x)爲類的本地變量
4、交互式模式下(常用於測試),變量名"_"用於保存最後表達式的結果
>>> 1+1
2
>>> print _
2
>>>
注:變量名(name)沒有類型,數據對象纔有類型;變量可以引用任意對象
>>> type(name) <type 'str'> >>> name=3.14 >>> type(name) <type 'float'> >>>
核心數據類型(python 一切皆對象,強類型語言):
數字:int,long,float,complex,bool
字符:str,unicode
列表:list
字典:dict
元組:tuple
文件:file
集合:set
類:class
None
其他文件類工具:pipes,fifos,sockets
類型轉換:
非字符轉換爲字符:str(),repr()或format()
>>> num1=5.61 >>> type(num1) <type 'float'> >>> num2=repr(num1) >>> type(num2) <type 'str'> >>> num3=format(num1) >>> type(num3) <type 'str'> >>>
int():正數轉換
float():浮點轉換
>>> num1=45 >>> num2=float(num1) >>> type(num1) <type 'int'> >>> type(num2) <type 'float'> >>>
list():將字串轉換爲列表
>>> str1="hello,world" >>> l1=list(str1) >>> print l1 ['h', 'e', 'l', 'l', 'o', ',', 'w', 'o', 'r', 'l', 'd'] >>> type(l1) <type 'list'>
tuples():將字串轉換爲元組
>>> t1=tuple(str1) >>> type(t1) <type 'tuple'> >>> print t1 ('h', 'e', 'l', 'l', 'o', ',', 'w', 'o', 'r', 'l', 'd') >>>
set():將字串轉換爲集合,無序去重
>>> s1=set(str1) >>> type(s1) <type 'set'> >>> print s1 set(['e', 'd', 'h', 'l', 'o', ',', 'r', 'w']) >>>
frozenset():將字串轉換爲不可變集合
dict():根據key-value元組序列,創建字典;
>>> l1=[('a',1),('b',11),('c',45)] >>> print l1 [('a', 1), ('b', 11), ('c', 45)] >>> d1=dict(l1) >>> print d1 {'a': 1, 'c': 45, 'b': 11} >>>
chr():將整數按ascii碼轉換爲字符
>>> num2=77 >>> type(num2) <type 'int'> >>> c1=chr(num2) >>> print c1 M >>> type(c1) <type 'str'> >>>
ord():將字符轉換爲整數值
hex():將整數轉換爲16進制字符串
bin():將整數轉換爲2進制字符串
oct():將整數轉換爲8進制字符串
>>> x=16 >>> str=hex(x) >>> print str 0x10 >>> str=bin(x) >>> print str 0b10000 >>> str=oct(x) >>> print str 020 >>> type(str) <type 'str'> >>>
數字操作符:
位移:>> 或 <<
>>> str=bin(x) >>> print str 0b10000 >>> str=bin(x>>2) >>> print str 0b100
邏輯與:&
>>> 1&0 0 >>> 1&1 1 >>>
邏輯或:|
>>> 1 | 1 1 >>> 1 | 0 1 >>> 0| 0 0 >>>
異或:^
>>> 1^0 1 >>> 1^1 0
取反:~
>>> 101 101 >>> ~101 -102 >>> num=101 >>> num1=101 >>> num2=-102 >>> print (bin(num1)) 0b1100101 >>> print (bin(num2)) -0b1100110 >>>
文檔字串:
>>> def printName(): ... "test function" ... print "hello,world" ... >>> printName() (()表示調用運算符,調用函數) hello,world >>> printName.__doc__ (不加()引用對象) 'test function' >>> printName().__doc__ hello,world >>> >>> dir(printName) ['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name'] >>> dir(printName()) hello,world ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] >>>
for循環比while循環執行速度快;
python中提供兩個內置函數range或xrange,用於定製for循環中特殊的循環
range:一次性返回連續的整數列表;
xrange:一次性產生一個數據元素,相對於range更節約內存空間;
In [55]: sum=0 In [56]: for i in range(1,101): ....: sum+=i ....: else: ....: print sum ....: 5050 In [57]: for i in xrange(1,101): sum+=i else: print sum ....: 10100
range用法:非完備遍歷(用於指定長度挑選元素);修改列表
In [5]: for i in range(0,len(s),2): print s[i], ...: h w a e y u i e t a k y u In [6]: s="how are you, fine thank you" In [8]: l1=[1,2,3,4,5] In [9]: for i in range(len(l1)): ...: l1[i]+=1 ...: else: ...: print l1 ...: [2, 3, 4, 5, 6]
zip:取得一個或多個序列爲參數,將給定序列中的並排的元素配成元組,返回這些元組的列表;當長度不同時,zip會以最短的序列長度爲準
zip用法:可在for循環中用於實現並行迭代;zip常用於動態創造字典
In [12]: l2=['a','b','c','d','e','f','g'] In [13]: l1=[1,2,3,4,5,6,7] In [14]: zip(l1,l2) Out[14]: [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f'), (7, 'g')] In [15]: keys=[1,2,3,4,5,6,7] In [16]: values=['mon','tus','wed','thu','fri','sat','sun'] In [17]: d={} In [19]: for (k,v) in zip(keys,values): d[k]=v else: ....: print d ....: {1: 'mon', 2: 'tus', 3: 'wed', 4: 'thu', 5: 'fri', 6: 'sat', 7: 'sun'}
字符串常見運算符:
[i]:索引運算符
[i:j]:切片運算
[i:j:stride]:擴展切片
切片結果將生成一個新內存對象;
字符串操作
>>> str="xiong chen" >>> str[0:] 'xiong chen' >>> str[0:5] 'xiong' >>> str[6:0:-1] 'c gnoi' >>> str[9] 'n' >>> str[-1] 'n' In [2]: str="xiong chen" In [3]: str[-3::-1] Out[3]: 'hc gnoix' In [4]: str[5::-1] Out[4]: ' gnoix' In [5]: #sum只適用於數字序列 In [5]: l1=[1,2,3,4] In [6]: sum(l1) Out[6]: 10 In [7]:
字符串常用方法
#s.capitalize():首字符大寫 In [11]: str.capitalize() Out[11]: 'Xiong chen' #s.index(sub):找到指定字符串sub首次出現的位置 In [9]: ''.join(l2) Out[9]: 'xiong chen' In [13]: str.index('c') Out[13]: 6 #s.join(t):s作爲分隔符,連接序列t中的字符串 In [7]: l2=list(str) In [8]: print l2 ['x', 'i', 'o', 'n', 'g', ' ', 'c',
python動態語言:
In [20]: import sys In [21]: sys.getrefcount()
增加對象對象的引用次數
1、對象創建
2、將對象添加進容器時,類似list.append()
3、當對象當作參數傳遞給函數時
減少引用次數
1、應用此對象的變量被顯示銷燬,del x
2、引用此對象的變量名重新賦值,
3、從容器中移除對象時,類似list.pop()
4、容器本身被銷燬
python迭代
迭代:重複做一件事
iterable(可迭代)對象:
1、支持每次返回自己包含的一個成員對象,從頭遍歷到尾部;
2、可迭代對象實現了__iter__方法
序列類型:如list,str,tuple
非序列類型:如dict,file
用戶自定義的一些包含了__iter__()或__getitem__()方法的類
In [23]: l1.__iter__() #在內存中創建了一個迭代器的可迭代對象 Out[23]: <listiterator at 0x246d4d0>
迭代器(iterator)又稱遊標(cursor),它是程序設計的軟件設計模式,是一種可以在容器上實現元素遍歷的接口;
迭代器是一種特殊的數據結構,在Python中以對象的形式存在;
簡單理解:對於一個集體中的每一個元素,想要執行遍歷,那麼針對這個集體的迭代器定義了遍歷集體中每個元素的順序或者方法;
#可迭代對象創建迭代器方法有兩種: In [24]: i1=l1.__iter__() In [25]: i1.next() Out[25]: 1 In [26]: i1.next() Out[26]: 2 In [27]: i2=iter(l1) In [28]: i2.next() Out[28]: 1 In [29]: i2.next() Out[29]: 2
在python中,迭代器是遵循迭代協議的對象
1、使用iter()可從任何序列對象中得到迭代器
2、若要實現迭代器,需要在類中定義next()方法,python3中是__next__()
3、要使得迭代器指向下一個元素,則使用成員函數next()
4、當沒有元素時,則引發StopIteration異常
5、for循環可以用於任何可迭代對象
for循環開始時,會通過迭代協議傳遞給iter()內置函數,從而能夠從可迭代對象中獲取一個迭代器,返回的對象含有需要的next()方法
根據已有列表生成新列表
#for循環 In [31]: l2=[] In [32]: for i in l1: ....: l2.append(i**2) ....: else: ....: print l2 ....: [1, 4, 9, 16, 25, 36, 49]
列表解析:比for循環快1倍
In [33]: l3=[i**2 for i in l1] In [34]: print l3 [1, 4, 9, 16, 25, 36, 49] In [36]: l4=[i**2 for i in l1 if i>=3] #(增加if條件處理) In [37]: print l4 [9, 16, 25, 36, 49]
輸出/var/log/目錄中以.log結尾的文件
In [39]: os.listdir('/var/log/') Out[39]: ['spooler', 'sa', 'vmware-caf', 'dmesg.old', 'ntpstats', 'rhsm', 'spice-vdagent.log', 'anaconda.program.log', 'anaconda.yum.log', 'anaconda.ifcfg.log', 'cups', 'btmp', 'vmware-vmsvc.log', 'gdm', 'lastlog', 'vmware-vmusr.log', 'secure', 'tallylog', 'cron', 'samba', 'prelink', 'yum.log', 'vmware-install.log', 'dmesg', 'Xorg.0.log.old', 'maillog', 'messages', 'vmware-tools-upgrader.log', 'ppp', 'anaconda.storage.log', 'wtmp', 'Xorg.0.log', 'audit', 'anaconda.log', 'ConsoleKit', 'anaconda.syslog', 'wpa_supplicant.log', 'httpd', 'boot.log', 'pm-powersave.log', 'dracut.log'] In [39]: os.listdir('/var/log/') #目錄中文件名爲列表 Out[39]: ['spooler', 'sa', 'vmware-caf', 'dmesg.old', 'ntpstats', 'rhsm', 'spice-vdagent.log', 'anaconda.program.log', 'anaconda.yum.log', 'anaconda.ifcfg.log', 'cups', 'btmp', 'vmware-vmsvc.log', 'gdm', 'lastlog', 'vmware-vmusr.log', 'secure', 'tallylog', 'cron', 'samba', 'prelink', 'yum.log', 'vmware-install.log', 'dmesg', 'Xorg.0.log.old', 'maillog', 'messages', 'vmware-tools-upgrader.log', 'ppp', 'anaconda.storage.log', 'wtmp', 'Xorg.0.log', 'audit', 'anaconda.log', 'ConsoleKit', 'anaconda.syslog', 'wpa_supplicant.log', 'httpd', 'boot.log', 'pm-powersave.log', 'dracut.log'] In [40]: In [41]: filelist2=[i for i in filelist1 if i.endswith('.log')] In [42]: print filelis filelist1 filelist2 In [42]: print filelist2 ['spice-vdagent.log', 'anaconda.program.log', 'anaconda.yum.log', 'anaconda.ifcfg.log', 'vmware-vmsvc.log', 'vmware-vmusr.log', 'yum.log', 'vmware-install.log', 'vmware-tools-upgrader.log', 'anaconda.storage.log', 'Xorg.0.log', 'anaconda.log', 'wpa_supplicant.log', 'boot.log', 'pm-powersave.log', 'dracut.log']
#列表之間交叉相乘 In [43]: l1=['x','y','z'] In [44]: l2=[1,2,3] In [45]: l3=[(i,j) for i in l1 for j in l2] In [46]: print l3 [('x', 1), ('x', 2), ('x', 3), ('y', 1), ('y', 2), ('y', 3), ('z', 1), ('z', 2), ('z', 3)] In [1]: l1=['x','y','z'] In [2]: l2=[1,2,3] In [3]: l3=[(i,j) for i in l1 for j in l2 if j != 1] #增加if判斷 In [4]: print l3 [('x', 2), ('x', 3), ('y', 2), ('y', 3), ('z', 2), ('z', 3)]
列表一次生成所有數據,佔用內存;與range類似,則有生成器,類似xrange;
生成器表達式並不真正創建數字列表,而是返回一個生成器對象,此對象在每一次計算出一個條目後,把這個條目“產生”yield處理
生成器使用惰性計算、或者延遲求值的機制
序列過長,並且每次只需要獲取一個元素時,應當考慮使用生成器表達式而不是列表解析器(生成器於Python2.4導入)
>>> [i**2 for i in range(1,11)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] >>> (i**2 for i in range(1,11)) <generator object <genexpr> at 0x0255C288> >>> g1=(i**2 for i in range(1,11)) >>> g1.next() 1 >>> g1.next() 4 >>> g1.next() 9 >>> g1.next() 16 >>> g1.next() 25 >>> g1.next() 36 >>> >>> for i in (i**2 for i in range(1,11)):print i/2, ... 0 2 4 8 12 18 24 32 40 50
enumerate產生偏移和元素
range可在非完備遍歷中用於生成索引偏移,而偏移處的元素;
如果同時需要偏移索引和偏移元素,則可以使用enumerate()函數;
此內置函數返回一個生成器對象
>>> url="www.baidu.com" >>> g1=enumerate(url) >>> g1.next() (0, 'w') >>> g1.next() (1, 'w') >>> g1.next() (2, 'w') >>> g1.next() (3, '.')
python文件對象
文件系統是os用於明確磁盤或分區上的文件的方法和數據結構--即在磁盤上組織文件的方法
概括來講:(變量:具有別名的內存地址)
1、文件是計算機中由OS管理的具有名字的存儲區域
2、在Linux系統上,文件被看做是字節序列
文件對象接口
python內置函數open()用於打開文件和創建文件對象;
open(name[,mode[,bufsize]])
open方法可以接收三個參數:name、mode、bufsize
open函數返回一個文件對象
mode指定文件的打開模式;簡單模式,r只讀,w寫入(首部輸入),a附加(尾部輸入);在模式後使用“+”,表示同時支持輸入、輸出操作;在模式後附加“b”表示以二進制方式打開
bufsize定義輸出緩存;0表示無輸出緩存,1表示使用緩存,負數表示使用系統默認設置,正數表示使用近似指定大小的緩衝
>>> dir(file) # 文件也是可迭代對象 ['__class__', '__delattr__', '__doc__', '__enter__', '__exit__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'closed', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines', 'xreadlines'] > >>> f1=open('c://tftpboot/BF50SW19-B3','r') >>> type(f1) <type 'file'> >>> f1.next() 'feature telnet\n' >>> f1.next() 'feature tacacs+\n' >>> f1.next() 'cfs eth distribute\n' >>> f1.close() >>> f1.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: I/O operation on closed file >>> f1=open('c://tftpboot/BF50SW20-B3','r') >>> f1.fileno() #文件描述符 3 >>> f1.readline() 'BF50SW20-B3(config)# copy ftp: bootflash:\n' >>> f1.readlines() #返回所有行組成的列表 ['Enter source filename: n5000-uk9.5.2.1.N1.5.bin\n', "Enter vrf (If no input, current vrf 'default' is considered): management\n", 'Enter hostname for the ftp server: 1.1.1.1\n', 'Enter username: anonymous\n', 'Password: \n', '***** Transfer of file Completed Successfully *****
>>> f1.tell() # 返回指針在文件中的位置 37612L #file.seek(offset[,whence]) #whence:起點,0從文件頭;1從當前位置;2從文件尾部 #offset:偏移量 >>> f1.tell() 37612L >>> f1.seek(0) >>> f1.tell() 0L >>> f1.read(10) 'BF50SW20-B' >>> f1.tell() 10L >>> f1.next() '3(config)# copy ftp: bootflash:\n' >>> f1.tell() 8363L >>> f1.name 'c://tftpboot/BF50SW20-B3' >>>
>>> f1=open('c://tftpboot/BF50SW19-B3','r+') >>> f1.next() 'feature telnet\n' >>> f1.seek(0,2) >>> f1.tell() 10709L >>> f1.write("new line\n") >>> f1.tell() 10719L >>> f1.close() >>> f2=open('c://tftpboot/test','w+') #---w/w+, 如果不存在,創建新文件 >>> f2.write('hello\n') >>> f2.close() >>> f3=open('c://tftpboot/test','r') >>> f3.next() 'hello\n' >>> f3.close() >>> f3=open('c://tftpboot/test1','r') #--- r/r+, 如果不存在,報錯 Traceback (most recent call last): File "<stdin>", line 1, in <module> IOError: [Errno 2] No such file or directory: 'c://tftpboot/test1' >>> f3=open('c://tftpboot/test1','r+') Traceback (most recent call last): File "<stdin>", line 1, in <module> IOError: [Errno 2] No such file or directory: 'c://tftpboot/test1' >>> f3=open('c://tftpboot/test1','w+') >>> f3.close()
>>> for line in (i**2 for i in range(1,11)): ... f3.write(str(line)+'\n') ... else: ... f3.close() ... >>> f3.flush() >>> f3=open('c://tftpboot/test1','r') >>> f3.readlines() ['1\n', '4\n', '9\n', '16\n', '25\n', '36\n', '49\n', '64\n', '81\n', '100\n'] >>>
>>> f4=open('c://tftpboot/test2','w+') >>> import os >>> l1=os.listdir('c://tftpboot') >>> print l1 ['BF50SW19-B3', 'BF50SW20-B3', 'BF50SW21-B3', 'BF50SW22-B3', 'test', 'test1', 'test2'] >>> f4.writelines(l1) >>> f4.flush() >>> f4.readlines() [] >>> f4.close() >>> f4.readlines()
>>> l2=[ i+'\n' for i in os.listdir('c://tftpboot')] >>> print l2 ['BF50SW19-B3\n', 'BF50SW20-B3\n', 'BF50SW21-B3\n', 'BF50SW22-B3\n', 'test\n', 'test1\n', 'test2\n'] >>> f4=open('c://tftpboot/test2','w+') >>> l2 ['BF50SW19-B3\n', 'BF50SW20-B3\n', 'BF50SW21-B3\n', 'BF50SW22-B3\n', 'test\n', 'test1\n', 'test2\n'] >>> f4.writelines(l2) >>> f4.seek(0) >>> f4.readlines() ['BF50SW19-B3\n', 'BF50SW20-B3\n', 'BF50SW21-B3\n', 'BF50SW22-B3\n', 'test\n', 'test1\n', 'test2\n'] >>> f4.flush() >>> f4.close()
>>> f4.isatty() False >>> f4.tell() 0L >>> f4.readline() 'BF50SW19-B3\n' >>> f4.tell() 13L >>> f4.truncate(f4.tell()) >>> f4.seek(0) >>> f4.readlines() ['BF50SW19-B3\n'] >>> f4.close() >>> f4=open('c://tftpboot/test2','w+') >>> f4.encoding >>> f4.mode 'w+' >>> f4.closed False >>> f4.newlines >>> f4.readline() '' >>> f4.newlines >>> f4.softspace 0 >>> f4.close() >>> f4.closed True
文件系統功能:os
>>> dir(os) ['F_OK', 'O_APPEND', 'O_BINARY', 'O_CREAT', 'O_EXCL', 'O_NOINHERIT', 'O_RANDOM', 'O_RDONLY', 'O_RDWR', 'O_SEQUENTIAL', 'O_SHORT_LIVED', 'O_TEMPORARY', 'O_TEXT', 'O_TRUNC', 'O_WRONLY', 'P_DETACH', 'P_NOWAIT', 'P_NOWAITO', 'P_OVERLAY', 'P_WAIT', 'R_OK', 'SEEK_CUR', 'SEEK_END', 'SEEK_SET', 'TMP_MAX', 'UserDict', 'W_OK', 'X_OK', '_Environ', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_copy_reg', '_execvpe', '_exists', '_exit', '_get_exports_list', '_make_stat_result', '_make_statvfs_result', '_pickle_stat_result', '_pickle_statvfs_result', 'abort', 'access', 'altsep', 'chdir', 'chmod', 'close', 'closerange', 'curdir', 'defpath', 'devnull', 'dup', 'dup2', 'environ', 'errno', 'error', 'execl', 'execle', 'execlp', 'execlpe', 'execv', 'execve', 'execvp', 'execvpe', 'extsep', 'fdopen', 'fstat', 'fsync', 'getcwd', 'getcwdu', 'getenv', 'getpid', 'isatty', 'kill', 'linesep', 'listdir', 'lseek', 'lstat', 'makedirs', 'mkdir', 'name', 'open', 'pardir', 'path', 'pathsep', 'pipe', 'popen', 'popen2', 'popen3', 'popen4', 'putenv', 'read', 'remove', 'removedirs', 'rename', 'renames', 'rmdir', 'sep', 'spawnl', 'spawnle', 'spawnv', 'spawnve', 'startfile', 'stat', 'stat_float_times', 'stat_result', 'statvfs_result', 'strerror', 'sys', 'system', 'tempnam', 'times', 'tmpfile', 'tmpnam', 'umask', 'unlink', 'unsetenv', 'urandom', 'utime', 'waitpid', 'walk', 'write'] #目錄爲文件系統功能; >>> os.mkdir('c://tftpboot/testdir') >>> os.getcwd() 'C:\\Users\\\xd0\xdc\xe8\xa1' >>> os.chdir('c://tftpboot') >>> os.getcwd() 'c:\\tftpboot' >>> os.stat('test2') nt.stat_result(st_mode=33206, st_ino=0L, st_dev=0, st_nlink=0, st_uid=0, st_gid=0, st_size=0L, st_atime=1490841609L, st_mtime=1490842487L, st_ctime=1490841609L) >>> os.listdir(os.getcwd()) ['BF50SW19-B3', 'BF50SW20-B3', 'BF50SW21-B3', 'BF50SW22-B3', 'test', 'test1', 'test2', 'testdir'] >>> >>> os.makedirs('a/b/c') >>> os.listdir(os.getcwd()) ['a', 'BF50SW19-B3', 'BF50SW20-B3', 'BF50SW21-B3', 'BF50SW22-B3', 'test', 'test1', 'test2', 'testdir'] >>> >>> os.removedirs('a/b/c') >>> os.listdir(os.getcwd()) ['BF50SW19-B3', 'BF50SW20-B3', 'BF50SW21-B3', 'BF50SW22-B3', 'test', 'test1', 'test2', 'testdir'] >>>
文件相關:
mkfifo()
mknod()
remove()
unlink()
rename()
stat():返回文件狀態信息
symlink:創建鏈接
utime():更新文件時間戳
tmpfile():創建並打開一個新的臨時文件
walk():文件目錄
>>> os.walk(os.getcwd()) <generator object walk at 0x029F1670> >>> g1=os.walk(os.getcwd()) >>> g1.next() ('c:\\tftpboot', ['testdir'], ['BF50SW19-B3', 'BF50SW20-B3', 'BF50SW21-B3', 'BF50SW22-B3', 'test', 'test1', 'test2']) >>>
#訪問權限 >>> os.access('test',0) True >>> os.access('test',500) True >>>
>>> os.chmod('test2',0640) #os.chown():修改屬主、屬組 #umask():設置默認權限模式
文件描述符
open()
read()
write()
設備文件
mkdev()
major()
minor()
跟文件路徑相關
>>> import os.path >>> dir(os.path) ['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_abspath_split', '_getfullpathname', 'abspath', 'altsep', 'basename', 'commonprefix', 'curdir', 'defpath', 'devnull', 'dirname', 'exists', 'expanduser', 'expandvars', 'extsep', 'genericpath', 'getatime', 'getctime', 'getmtime', 'getsize', 'isabs', 'isdir', 'isfile', 'islink', 'ismount', 'join', 'lexists', 'normcase', 'normpath', 'os', 'pardir', 'pathsep', 'realpath', 'relpath', 'sep', 'split', 'splitdrive', 'splitext', 'splitunc', 'stat', 'supports_unicode_filenames', 'sys', 'walk', 'warnings'] >>>
basename():路徑基名
dirname():父目錄名
>>> file1=os.path.basename('c:\\tftpboot\\test') >>> dir1=os.path.dirname('c:\\tftpboot\\test') >>> file1 'test' >>> dir1 'c:\\tftpboot' >>> os.path.join(dir1,file1) 'c:\\tftpboot\\test'
split():返回(dirname()、basename())元組
splitext:返回(filename,extension)元組
getatime()
getctime()
getmtime()
getsize():返回文件的大小
查詢:
exists():判斷指定文件是否存在
isabs():判斷指定路徑是否爲絕對路徑
isdir():是否爲目錄
isfile():是否爲文件
islink():是否符號鏈接
ismount():是否爲掛載點
samefile():兩個路徑是否指向同一個文件
練習:判斷文件是否存在,存在則打開 ;讓用戶通過鍵盤反覆輸入多行數據,追加保存至文件中。
filename=’c:\\tftpboot\\test’ if os.path.isfile(filename): f1=open(filename,’a+’) while true: line=raw_input(‘enter something>’) if line==’q’ or line==’quit’: break f1.write(line+’\n’) else: f1.close()
對象的持久存儲
pickle
marshal
dbm接口:數據庫接口
shevle流式並存入數據庫
>>> d1={'x':123,'y':234,'z':345} >>> f5=open('a','w+') >>> pickle.dump(d1,f5) >>> f5.readlines() >>> f6=open('a') >>> d2=pickle.load(f6) >>> print d2 {'y': 234, 'x': 123, 'z': 345} >>>
函數是python爲了代碼最大程度的重用和最小化代碼冗餘而提供的基本程序結構
函數是一種設計工具,它能讓程序員將複雜的系統分解爲可管理的部件
函數用於將相關功能打包並參數化
在python中可以創建4種函數
1、全局函數,定義在模塊種
2、局部函數,嵌套於其他函數種
3、lambda函數,表達式
4、方法,於特定數據類型關聯的函數,並且只能與數據類型關聯一起使用
python提供了很多內置函數
創建函數def
def是一個可執行語句;因此可以出現在任何能夠使用語句的地方,甚至可以嵌套在其他語句種
def創建了一個對象並將其複製給一個變量名(即函數名)
return用於返回結果對象,其爲可選;無return語句的函數自動返回none對象;返回多個值時,彼此用逗號分隔,且組合爲元組形式返回一個對象
def語句運行之後,可以在程序種通過函數後附加括號進行調用
函數作用域
python創建、改變或者查找變量名都是在名稱空間種進行
在代碼種變量名被賦值的位置決定了其能被訪問到的範圍
函數定義了本地作用域,而模塊定義了全局作用域
1、每個模塊都是一個全局作用域,因此,全局作用域的範圍僅限於單個程序文件
2、每次對函數的調用都會創建一個新的本地作用域,賦值的變量除非聲明爲全局變量,否則均爲本地變量
3、所有的變量名都可以歸納爲本地、全局或內置的(由__builtin__模塊提供)
變量名解析:LEGB規則
本地函數 > 外層函數 > 全局 > 內置
local(function) > enclosing function locals(外層函數) > global(module) > builtin(python)
>>> def f1(): ... x=3 ... def f2(): ... y="hello" ... print x,y ... return f2 ... >>> type(f1) <type 'function'> >>> f1()() 3 hello
函數參數
>>> def f1(x): ... print x ... >>> f1(4) 4 >>> f1("abc") abc >>> def f2(x,y): ... print x+y ... >>> f2(3,4) 7 >>> f2("hello ","world") hello world >>>
參數傳遞
>>> m=3;n=4 >>> def f3(x,y): ... x-=1 ... print x,y ... >>> f3(m,n) 2 4 >>> print m,n 3 4 >>> >>> >>> def f5(x): ... x.pop() ... print x ... >>> l1=[1,2,3,4] #----可變對象在函數內部可以修改 >>> f5(l1) [1, 2, 3] >>> print l1 [1, 2, 3] >>> f5(l1[:]) #---- 可變參數副本 [1, 2] >>> print l1 [1, 2, 3]
參數匹配模型:
默認情況下,參數通過其位置進行傳遞,從左至右,這意味着,必須精確的傳遞和函數頭部參數一樣多的參數
參數傳遞形式:從左向右,按關鍵名稱匹配,
>>> m=3;n=4 >>> def f3(x,y): ... x-=1 ... print x,y ... >>> f3(m,n) 2 4 >>> f3(y=n,x=m) 2 4
關鍵字參數:使用“name=value”的語法通過參數名進行匹配
混用時:位置參數放在關鍵字參數前面
>>> def f5(x,y,z): ... print x,y,z ... >>> f5(m,n,0) 3 4 0 >>> f5(x=m,y=n,z=0) 3 4 0 >>> f5(m,z=0,y=n) 3 4 0
默認參數:定義函數時使用“name=value”的語法直接給變量一個值,從而傳入的值可以少於參數個數;
混用默認值和無默認值的參數時,無默認值參數放前面
In [2]: def f1(x,y,z=9): ...: print x,y,z ...: In [3]: f1(3,4,4) 3 4 4 In [4]: f1(3,4) 3 4 9 In [6]: def f2(x=1,y,z=9): 有默認參數放在右邊 ...: print x,y,z ...: File "<ipython-input-6-6fde60cb511a>", line 1 def f2(x=1,y,z=9): SyntaxError: non-default argument follows default argument
可變參數:定義函數使用*開頭的參數,可用於收集任意多基於位置或關鍵字的參數
調用函數時使用可變參數要求:
定義函數時使用*:收集位置參數
定義函數時使用**:收集關鍵字參數
In [7]: def f3(*x): ...: print x ...: In [8]: f3(3) (3,) In [9]: f3(3,4) (3, 4) In [10]: f3(3,4,7) (3, 4, 7) In [11]: def f4(**x): ....: print x ....: In [12]: f4(x=1,y=2,z=9) {'y': 2, 'x': 1, 'z': 9} In [13]: def f5(x,*y): #--- *y收集位置參數 ....: print x,y ....: In [14]: f5(3,4,5) 3 (4, 5) In [15]: def f6(x,y=10,*z): ....: print x ....: print y ....: print z ....: In [16]: f6(3,4,5) 3 4 (5,) In [17]: def f7(*x,**y): #--- *x收集位置參數,**y收集關鍵字參數 ....: print x ....: print y ....: In [18]: f7(3,4,5,i=3,j=6) (3, 4, 5) {'i': 3, 'j': 6}
可變參數解包:調用函數,使用*開頭的參數,可用於將參數集合打散,從而傳遞任意多基於位置或關鍵字的參數
In [19]: l1=[3,4,5] In [20]: x,y,z=l1 In [21]: print x,y,z 3 4 5 In [22]: def f8(x,y,z): ....: print x,y,z ....: In [23]: f8(*l1) 3 4 5 In [24]: l2=['a','b','c','d'] In [25]: f8(*l2) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-25-c4c448bb7bdc> in <module>() ----> 1 f8(*l2) TypeError: f8() takes exactly 3 arguments (4 given) In [26]: l3=['a','b'] In [27]: f8(*l3) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-27-d3a5d34fd4bd> in <module>() ----> 1 f8(*l3) TypeError: f8() takes exactly 3 arguments (2 given) In [28]: def f9(x,*y): ....: print x ....: print y ....: In [29]: f9(3,*l3) 3 ('a', 'b') In [30]: d1={'a':1,'b':2,'c':3} In [31]: def f10(x,*y,**z): ....: print x ....: print y ....: print z ....: In [32]: m=3 In [33]: f10(m,*l3,**d1) 3 ('a', 'b') {'a': 1, 'c': 3, 'b': 2}
lambda運算符
lambda args: expression
args:以逗號分隔的參數列表
expression:用到args中各參數的表達式
In [34]: lambda x,y: x+y Out[34]: <function __main__.<lambda>> In [34]: lambda x,y: x+y Out[34]: <function __main__.<lambda>> In [35]: f1=lambda x,y: x+y In [36]: f1(3,4) Out[36]: 7
lambda語句定義的代碼必須是合法的表達式,不能出現多條件語句(可使用if的三元表達式)和其他非表達式語句,如for和while;
lambda的首要用途是指定短小的回調函數
lambda將返回一個函數而不是將函數賦值給某變量名; 對某個對象做出不同的處理時,把每次處理機制定義爲Lambda
In [37]: l3=[(lambda x:x*2),(lambda y:y*3)] In [38]: for i in l3: ....: print i(4) ....: 8 12
函數式編程
在某個函數中調用其它函數,將函數當作參數使用
也稱爲泛函編程,是一種編程範式;函數作爲參數傳遞給另一個函數;從而實現在一個函數中調用其他函數;
filter(func,seq):調用一個bool函數來迭代遍歷每個seq中的函數;返回一個使func返回值爲true的元素序列
map(func,seq1[,seq2…]):將函數作爲func作用於給定序列seq中每一個元素,並用一個列表來提供返回值:如果func爲None,func表現爲一個身份函數,返回一個含有每個序列中元素集合的n個元組的列表
reduce(func,seq[,init]):將二元函數作用於seq序列的元素,每個攜帶一對(先前的結果以及下一個序列元素),連續的將現有的結果和下一個值作用於獲得的隨後的結果上,最後減少我們的序列爲一個單一的返回值,如果初始值init給定,第一個比較會使Init和第一個序列元素而不是序列的頭兩個元素
filter(過濾器)
filter()爲已知的序列的每個元素調用給定的布爾函數
調用中,返回值爲非零值得元素將被添加至一個列表中
In [2]: l1=[1,2,33,23,42,44] In [3]: def f1(x): if x>20:return True ...: else: ...: False ...: In [4]: filter(f1,l1) Out[4]: [33, 23, 42, 44]
map(映射器)
map()將函數調用“映射”到每個序列的對應元素上,並返回一個含有所有返回值的列表
帶有單個隊列的map()
In [5]: l1=[0,1,2,3,4,5,6] In [6]: l2=['sun','mon','tue','wed','thu','fri','sat'] In [7]: map(f1,l1,l2) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-7-938c23fc23f4> in <module>() ----> 1 map(f1,l1,l2) TypeError: f1() takes exactly 1 argument (2 given) In [8]: map(f1,l1) Out[8]: [None, None, None, None, None, None, None] In [9]: map(f1,l2) Out[9]: [True, True, True, True, True, True, True] In [10]: map(None,l1,l2) Out[10]: [(0, 'sun'), (1, 'mon'), (2, 'tue'), (3, 'wed'), (4, 'thu'), (5, 'fri'), (6, 'sat')]
reduce(摺疊)
In [15]: def f3(x,y): ....: return x+y ....: In [16]: l1 Out[16]: [0, 1, 2, 3, 4, 5, 6] In [17]: reduce(f3,l1) Out[17]: 21 In [18]: reduce(f3,l1,10) Out[18]: 31
python閉包,外部函數爲內部函數提供環境,內部函數:
外層函數返回後,內層函數仍然可以使用外層函數中的變量(內層函數的環境);
In [19]: def f1(x): ....: def f2(y): ....: return y**x ....: return f2 ....: In [24]: f3=f1(3) In [25]: f3(2) Out[25]: 8 In [26]: f3(4) Out[26]: 64 In [27]: f3=f1(4) In [28]: f3(3) Out[28]: 81 In [29]: f3(2) Out[29]: 16 In [33]: def startPos(m,n): def newPos(x,y): print "last P is (%d,%d),and the new P is (%d,%d)" %(m,n,m+x,n+y) return newPos ....: In [34]: action=startPos(10,10) In [35]: action(1,2) last P is (10,10),and the new P is (11,12) In [36]: action(-1,3) last P is (10,10),and the new P is (9,13)
python閉包:定義在外層函數,在內層函數引用的變量;在外層函數直接返回內層函數,作爲返回結果;還可以使用外層函數變量,記憶的效果;
閉合作用:調用返回時,內部函數會消失;通過閉合,內層函數記憶了,外層函數中內層函數調用過的變量;
例子:內層函數f2()可以記錄外層函數f1()的變量x,外層函數f1()爲內存函數f2()提供外部運行環境;
In [4]: def f1(x): ...: def f2(y): ...: return y ** x ...: return f2 ...: In [5]: f2=f1(3) In [6]: f2(2) Out[6]: 8 In [7]: f2(3) Out[7]: 27 In [8]: f2(4) Out[8]: 64
棋盤,棋子行走;外部函數定義當前位置,內層函數計算行走路徑;
In [9]: def startPos(m,n): ...: def newPos(x,y): ...: print "the old position is (%d,%d), and the new position is (%d,%d)." % (m,n,m+x,n+y) ...: return newPos ...: In [10]: action=startPos(10,10) In [11]: action(1,2) the old position is (10,10), and the new position is (11,12). In [12]: action(-1,3) the old position is (10,10), and the new position is (9,13).
裝飾器(閉包的進一步應用)
1、裝飾器自身是一個函數,用於裝飾其他函數;實現函數功能在不同環境中適用,代碼重用;
常用於切面需求的場景,插入日誌、性能測試、事務處理等;可以抽離大量函數無關的功能,
2、功能及作用:增強被裝飾函數的功能;
3、接收一個函數對象作爲參數,以對其進行增強;
In [14]: def deco(func): def wrapper(): print "please say something:" func() print "no zuo no die" return wrapper ....: In [16]: @deco def show(): print "i am form Mars" ....: In [17]: show() please say something: i am form Mars no zuo no die In [18]:
帶參數的裝飾器
內層函數接收外層函數的參數,並且傳遞給被裝飾函數,被調用時傳遞參數
In [18]: def deco(func): ....: def wrapper(x): ....: print "please say something" ....: func(x) ....: print "no zuo no die" ....: return wrapper ....: In [20]: @deco ....: def show(x): ....: print x ....: In [21]: show("hello mars") please say something hello mars no zuo no die
函數的設計規範:
耦合性:
1、通過參數接收輸入,以及通過return產生輸出以保證函數的獨立性
2、儘量減少使用全局變量進行函數間通信
3、不要再函數中修改可變類型的參數
4、避免直接改變定義在另外一個模塊中的變量
聚合性:
1、每個函數都應該有一個單一、統一的目標
2、每個函數的功能都應該相對簡單
面向對象編程
程序=指令+數據
代碼可以選擇以指定爲核心或以數據爲核心進行編寫
兩種類型:
1、以指令爲中心:圍繞“正在發生”進行編寫
面向過程編程:程序具有一系列線性步驟:主體思想是代碼作用於數據
2、以數據爲核心:圍繞“將影響誰”進行編寫
面向對象編程(oop):圍繞數據及爲數據嚴格定義的接口來組織程序,用數據控制對代碼的訪問
面向對象的核心概念
所有編程語言的目的都是提供一種抽象方法
在機器模型(“解空間”)與實際解決的問題模型(”問題空間“)之間,程序員必須建立一種聯繫
面向過程:程序=算法+數據結構
面向對象:將問題空間中的元素以及他們在解空間中的表示物抽象爲對象,並允許通過問題來描述問題而不是方案;可以把對象想象成一種新型變量,它保存着數據,但可以對自身的數據執行操作
類型由狀態集合(數據)和轉換這些狀態的操作集合組成
類抽象:
類:定義了被多個同一類型對象共享的結構和行爲(數據和代碼)
類的數據和代碼:即類的成員
數據:成員變量或實例變量
成員方法:簡稱爲方法,是操作數據的代碼,用於定義如何使用成員變量;因此一個類的行爲和接口是通過方法來定義的
方法和變量:
私有:內部使用
公共:外部可見
面向對象的程序設計方法
1、所有東西都是對象
2、程序是一大堆對象的組合
通過消息傳遞,各對象知道自己該做什麼
消息:即調用請求,它調用的是從屬於目標對象的一個方法
3、每個對象都有自己的存儲空間,並可容納其他對象
通過封裝現有對象,可以製作成新型對象
4、每個對象都屬於一種類型
類型:即類
對象是類的實例
類的一個重要特性爲”能發什麼樣的消息給它“
5、同一個類的所有對象都能接收相同的消息
對象的接口
1、定義一個類後,可以根據需要實例化出多個對象
2、如何利用對象完成真正有用的工作?
首先,必須有一種方法能向對象發送請求,令其做一些事情
其次,每個對象僅能接收特定的請求
能向對象發送的請求由其”接口“進行定義
對象的”類型“或”類“則規定了它的接口形式
例如:類型名:light
接口:on(),off(),brighten(),dim()
類:將同一種具體物事的共同特性抽象出來的表現;
狀態和轉換狀態的操作;狀態爲數據,轉換操作爲方法;
類間的關係
依賴:(use-a)
一個類的方法操縱另一個類的對象
聚合(has-a)
類A的對象包含類B的對象
繼承(is-a)
描述特殊與一般的關係
面向對象編程的原則:封裝、繼承及多態
封裝的作用
1、隱藏實現方案細節
2、將代碼及其處理的數據綁定在一起的一種編程機制,用於保證程序和數據不受外部干擾且不會被誤用
繼承的作用
1、一個對象獲得另一個對象屬性的過程;用於實現按層分類的概念
2、一個深度繼承的子類繼承了類層次中它的每個祖先的所有屬性
3、超類、基類、父類
4、子類、派生類
多態的作用
1、允許一個接口被多個通用的類動作使用的特殊,具體使用哪個動作與應用場合相關
2、“一個接口,多個方法”
用於爲一組相關的動作設計一個通用的接口,以降低程序複雜性
python類和實例
類是一種數據結構,可用於創建實例
一般情況下,類封裝了數據和可用於該數據的方法
python類是一個可調用對象,即類對象,()調用方法
python2.2之後,類是一種自定義類型,而實例則是聲明某個自定義類型的變量
實例初始化
通過調用類來創建實例(instance=ClassName(args…))
類在實例化時可以使用__init__和__del__兩個特殊的方法
python中創建類
python使用關鍵字class關鍵字創建類,語法格式如下:
1、class ClassName(bases):
class documentation string
class suite
2、超類是一個或多個用於繼承的父類的集合
3、類體可以包含:聲明語句、類成員定義、數據屬性、方法
注意:
如果不存在繼承關係,ClassName後面的bases可以不提供
類文檔可選
Class語句的一般形式(駝峯命名方式)
class ClassName(bases):
date=value --- 數據屬性,類屬性
def method(self,…): --- 方法屬性,self對自身實例實施操作
self.member=value --- 實例屬性
In [1]: class TestClass(): ...: pass ...: In [2]: type(TestClass) Out[2]: classobj In [3]: obj1=TestClass() In [4]: type(obj obj1 object In [4]: type(obj1) Out[4]: instance
python中,class語句類似def,是可執行代碼;直到運行class語句後類纔會存在
In [5]: class FirstClass: --- 類名
...: spam=30 --- 類數據屬性
...: def display(self): --- 類方法,屬於可調用的屬性
...: print self.spam
...:
In [6]: x=FirstClass() --- 創建類實例
In [7]: x.display() --- 方法調用
30
class語句內,任何賦值語句都會創建類屬性;
每個實例對象都會繼承類的屬性並獲得自己的名稱空間
python類方法及調用
1、實例(對象)通常包含屬性
可調用的屬性:方法,object.method()
數據屬性
2、在opp中,實例就像是帶有“數據”的記錄,而類是處理這些記錄的“程序”
a.通過實例調用方法相當於調用所屬類的方法來處理當前實例
b.類似instance.method(args…)會被自動轉換爲class.method(instance,args…),如前面的例子,x.display()會被自動轉換爲FirstClass.display(x),即調用類的方法來處理實例x
c.因此,類中每個方法必須具有self參數
d.在方法內對self屬性做賦值運算會產生每個實例自己的屬性
e.python規定,沒有實例,方法不允許被調用,此即爲“綁定”
In [8]: class ThirdClass(): ...: data="hello ThirdClass" ...: def setdata(self,x): ...: self.str=x ...: def printdata(self): ...: print self.str ...: In [9]: ins1=ThirdClass() In [10]: ins1.data Out[10]: 'hello ThirdClass' In [11]: ins1.setdata("cxiong") In [12]: ins1.printdata() cxiong
python類和實例的屬性
1、class語句中的賦值語句會創建類屬性,如前面例子中的spam
2、在類方法中對傳給方法的特殊參數self進行賦值會創建實例屬性
In [13]: class MyClass(): ....: gender='Male' #---- 類屬性 ....: def setName(self,who): ....: self.name=who # ---- 實例屬性,實例化後調用執行 ....: In [14]: x=MyClass() In [15]: y=MyClass() In [16]: x.gender #--- 通過爬樹搜索,gender屬性會從MyClass類中獲取到 Out[16]: 'Male' In [17]: x.name #--- 在setName方法調用之前,MyClass類不會把name屬性附加到實例x上,當然也可以重裝__init__創建構造器直接爲實例提供 --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-17-ebfcbb65f7c8> in <module>() ----> 1 x.name AttributeError: MyClass instance has no attribute 'name' In [18]: x.setName('tom') In [19]: x.name Out[19]: 'tom' In [20]: y.setName('jerry') In [21]: y.gender,y.name Out[21]: ('Male', 'jerry') In [22]: x.gender,x.name Out[22]: ('Male', 'tom')
python構造器
創建實例時,python會自動調用類中的__init__方法,以隱形地爲實例提供屬性
1、__init__方法被稱爲構造器
2、如果類中沒有定義__init__方法,實例創建之初僅是一個簡單的名稱空間
__varname__():python解釋器自動調用
In [33]: class MyClass(): ....: data="hello MyClass" ....: def __init__(self,who): ....: self.name=who ....: In [34]: x=MyClass("tom") In [35]: y=MyClass("jerry") In [36]: x.data Out[36]: 'hello MyClass' In [37]: x.name Out[37]: 'tom' In [38]: y.data Out[38]: 'hello MyClass' In [39]: y.name Out[39]: 'jerry' In [40]: class Animal: ....: name="someone" #--- 數據屬性(成員變量) ....: def __init__(self,voice='hi'): #--- 重載構造函數,默認值=hi ....: self.voice=voice ....: def __del__(self): #--- 重裝析構函數 ....: pass #--- 省略 ....: def saySomething(self): #---方法屬性(成員函數) ....: print self.voice ....: In [41]: tom=Animal() #----創建實例 In [42]: tom.saySomething() #--- 調用實例方法 hi In [43]: jerry=Animal('hello!') In [44]: jerry.saySomething() #--- 調用實例方法 hello!
類的特殊屬性
可以使用類的__dict__字典或python內置的dir()函數來獲取類的屬性,可用類的屬性和方法
In [47]: dir(MyClass) Out[47]: ['__doc__', '__init__', '__module__', 'data'] In [48]: MyClass.__dict__ Out[48]: {'__doc__': None, '__init__': <function __main__.__init__>, '__module__': '__main__', 'data': 'hello MyClass'}
實例屬性
實例僅擁有數據屬性(嚴格意義上來說,方法是類屬性)
1、通常通過構造器__init__爲實例提供屬性
2、這些數據屬性獨立於其他實例或類
3、實例釋放時,其屬性也將被清除
內建函數dir()或實例的特殊屬性__dict__可用於查看實例屬性
In [49]: dir(x) Out[49]: ['__doc__', '__init__', '__module__', 'data', 'name'] In [50]: x.__dict__ Out[50]: {'name': 'tom'}
實例的特殊屬性
方法的可用變量
1、實例變量:指定變量名稱及實例自身進行引用,self.變量名
2、局部變量:方法內部創建的變量,可直接使用
3、類變量(靜態變量):通過指定變量名與類名進行引用,類名.變量名
4、全局變量:直接使用
In [51]: class c(): ....: d1="hell c class" ....: def __init__(self,x): ....: self.insdata=x ....: In [52]: i1=c(50) In [53]: i2=c(100) In [54]: i1.d1 Out[54]: 'hell c class' In [55]: i2.d1 Out[55]: 'hell c class' In [56]: i1.d1="new value" In [57]: i1.d1 Out[57]: 'new value' In [58]: i2.d1 Out[58]: 'hell c class' In [59]: c.d1 Out[59]: 'hell c class' In [60]: c.d1="class new value" #---靜態變量修改 影響所有實例 In [61]: i1.d1 Out[61]: 'new value' In [62]: i2.d1 Out[62]: 'class new value'
繼承
繼承描述了基類的屬性如何”遺傳“給派生類
1、子類可以繼承它的基類的任何屬性,包括數據屬性和方法
2、一個未指定基類的類,其默認有一個名爲object的基類
3、python允許多重繼承
創建子類
1、創建子類時,只需在類名後跟一個或從其中派生的父類
2、
python中幾乎所有屬性的獲取都可以使用object.attribute的格式;
不過,此表達式會在Python中啓動搜索一一搜索連續的樹
class語句會產生一個類對象,對class的調用會創建實例,實例自動連接至創建此實例的一個或多個類
類連接至其超類的方式
將超類在類頭部的括號內,其從左向右的順序會決定樹中的次序
由下至上,由左至右
圖中所有的對象都是名稱空間,而繼承就是由下而上搜索此樹來尋找屬性名稱所出現的最低的位置
繼承方法專用化
繼承會先在子類尋找變量名,然後才查找超類,因此,子類可以對超類的屬性重新定義來取代繼承而來的行爲
1、子類可以完全取代從超類繼承而來的屬性
2、也可以通過已覆蓋的方法回掉超類來擴展超類的方法
In [70]: class ParClass(object): ....: def setInfo(self,sex='male'): ....: self.gender=sex ....: In [71]: class ChiClass(ParClass): ....: def setInfo(self,who): ---- 覆蓋父類的setInfo方法 ....: self.name=who ....: In [72]: x=ChiClass() In [73]: x.setInfo("tom") In [74]: x.name Out[74]: 'tom' In [75]: x.gender --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-75-dcfdb2ec694c> in <module>() ----> 1 x.gender AttributeError: 'ChiClass' object has no attribute 'gender' In [76]: class ChiClass(ParClass): def setInfo(self,who): self.name=who ....: ParClass.setInfo(self) --- 回調用父類的方法 ....: In [77]: x=ChiClass() In [78]: x.setInfo("tom") In [79]: x.name Out[79]: 'tom' In [80]: x.gender Out[80]: 'male'
issubclass()
布爾函數,判斷一個類是否由另一個類派生,語法:issubclass(sub,sup)
isinstance()
布爾函數,判斷一個對象是否是給定類的實例,語法isinstance(obj1,class_obj2)
hasattr()
布爾函數,判斷一個對象是否擁有指定的屬性,語法hasattr(obj,attr)
類似還有getattr(),setattr()和delattr()
super()
在子類中找出其父類以便於調用其屬性
一般情況下僅能採用非綁定方式調用祖先類方法
而super()可用於傳入實例或類型對象,語法super(type[,obj])
運算符重載
運算符重載是指在方法中攔截內置的操作--當類的實例出現在內置操作中,python會自動調用自定義的方法,並且返回自定義方法的操作結果
1、運算符重載讓類攔截常規Python運算
類可重載所有Python表達式運算符
類也可重載打印、函數調用、屬性點號運算等內置運算
2、重載使類實例的行爲像內置類型
3、重載通過提供特殊名稱的類方法實現
運算符重載並非必需,並且通常也不是默認的
可調用對象
函數
內置函數
自定義函數 def lambda
函數操作,()運算符
類
類方法
函數的屬性:
__doc__
__name__
__dict__
__code__
__globals__
方法的屬性:
__doc__
__name__
__class__:方法所屬的類
__func__:實現該方法的函數對象
__self__:調用此方法的實例
內置函數:
__doc__
__name__
__self__
類:
__doc__
__name__
__bases__
__dict__
__module__:定義了當前類的模塊名稱
實例:
__class__
__dict__