目錄:
參照內容:經典Django教程《Python+Django+Web開發指南》
重點概念:
交互解釋器tab還是空格對象的布爾值經典除法 真正除法內置數字工廠序列列表,字符串,元組列表推導式生成器表達式不可變字符串指示符內置序列函數表達式 語句匿名函數 lambda垃圾自動回收動態實例屬性Django提供了一個高級的框架,用它只需要很少代碼就可以完成一個Web應用。
Django使用Python寫成的,Python是一門OOP的開發語言,同時兼具系統語言(C、C++、java)的強大和腳本語言(Ruby和VB)的靈活迅速。
本節主要總結Django工程師一定要知道的Python概念,而不是一份通用的Python教程。
http://m.survivalescaperooms.com/ganiks
Python Shell中,不用去創建和保存一個源文件,就可以直接把代碼拿來測試。
>>> PRint 'Hello world!'Hello World!來看一個復雜的例子:
ganiks.liu@MAMIS-GAIKS-LIU /E/mysite (master)$ pythonPython 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32Type "help", "copyright", "credits" or "license" for more information.>>> for Word in ['capitalize', 'these', 'words']:... print word.upper() File "<stdin>", line 2 print word.upper() ^IndentationError: expected an indented block>>> for word in ['capitalize', 'these', 'words']:... print word.upper()...CAPITALIZETHESEWORDS>>> for i in rang(0,5):... print i...Traceback (most recent call last): File "<stdin>", line 1, in <module>NameError: name 'rang' is not defined>>> for i in range(0,5):... print i...01234>>>python語法中重要的一個方面就是沒有區分代碼庫的花括號{ }, 而是用對齊來替代
iPythoniPython的能力完全是另一個數量級上的解釋器。它提供了系統shell訪問、命令行技術、自動對齊、命令行歷史等許多特性。
要是能在Python的解釋器中調試Django應用是不是很酷?
變量和賦值 —— 除非你想解釋器詢問更多信息,否則你不可能百分百確定變量在任何給定的時刻是什么類型的對象
$ pythonPython 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32Type "help", "copyright", "credits" or "license" for more information.>>> foo = 'bar'>>> foo'bar'>>> type(foo)<type 'str'>>>> foo = 1>>> type(foo)<type 'int'>>>>條件語句的()
Python的作者:只有干凈和容易閱讀的代碼才能避免混亂
所有的Python值都可以表示為布爾值,這個的用處在哪里?
在于if和while語句里面做條件判斷~
>>> download_complete = False>>> bool(download_complete)False>>> bool(-1.2)True>>> bool("")False>>> bool([None])True>>> bool([None, 0])True>>> bool([])False>>>**python只有一種整數類型**>>> type(3.75)<type 'float'>>>> type(0377)<type 'int'>>>> type(0xE8C6)<type 'int'>>>> type(2+2j)<type 'complex'>+ - */ floor division 經典除法(整數相除結果取整,浮點相除結果取浮點)// true division 真正的除法 (統統取整數結果)& | ~ ^ >> << &= <<=關于 / //
In [8]: 1/2Out[8]: 0In [9]: 1.0/2Out[9]: 0.5In [10]: 1.0/2.0Out[10]: 0.5In [11]: 1/2.0Out[11]: 0.5In [12]: 1//2Out[12]: 0In [13]: 1.0//2Out[13]: 0.0In [14]: 1.0//2.0Out[14]: 0.0In [15]: 1//2.0Out[15]: 0.0In [16]: type(1//2.0)Out[16]: floatIn [17]: type(1//2)Out[17]: int>>> int('123')123>>> int(45.67)45>>> round(1.15, 1)1.1>>> float(10)10.0>>> divmod(15, 6)(2, 3)>>> ord('a')97>>> chr(65)'A'>>>序列類型類似其他語言中的數組,不同的是:
常見的序列有:
,)像數組一樣, 序列可以直接索引:
>>> s = 'Python'>>> s[0]'P'>>> s[4]'o'>>> s[-1]'n'還可以一次索引多個元素,在這里成為序列切片
>>> s[1:4]'yth'>>> s[3:]'hon'>>> s[3:-1]'ho'>>> s[:]'Python'>>> str(s)'Python'切片語法適用于所有的序列,包括字符串、元組、列表
其他的序列操作符還有連接, 復制, 檢查是否是成員
>>> 'Python and ' + 'Django are cool''Python and Django are cool'>>> 'Python and ' 'Django are cool''Python and Django are cool'>>> '-'*40'----------------------------------------'>>> 'an' in 'Django'True>>> 'xyz' in 'Django'False建避免在序列上使用 + 操作符,因為其效率不高
>>> 'foo'+'bar''foobar'#建議使用下面兩種方式>>> '%s%s' % ('foo', 'bar')'foobar'>>> s=''>>> s.join(['foo', 'bar'])'foobar'>>> book=['python', 'develop', 8]>>> book.append(2008)>>> book.insert(1, 'web')>>> book['python', 'web', 'develop', 8, 2008]>>> book[:3]['python', 'web', 'develop']>>> 'django' in bookFalse>>> book.remove(8)>>> book.pop(-1)2008>>> book['python', 'web', 'develop']>>> book*2['python', 'web', 'develop', 'python', 'web', 'develop']>>> book.extend(['with', 'django'])>>> book['python', 'web', 'develop', 'with', 'django']>>> book.extend([])>>> book.extend(['end'])>>> book['python', 'web', 'develop', 'with', 'django', 'end']>>> book.sort()>>> book['develop', 'django', 'end', 'python', 'web', 'with']這里注意一點跟string字符串的區別,列表的內置函數如sort, append, insert都是直接對對象進行修改,而沒有返回值;字符串比如用upper方法則是返回了一個字符串。
這是因為字符串是不可改變的,而列表可變
python2.4以上版本提供了sorted和reversed方法可以接受一個列表作為參數并返回一個處理過的拷貝
>>> book=['c','b',4,1,'a',2,3]>>> sbook = sorted(book)>>> sbook[1, 2, 3, 4, 'a', 'b', 'c']>>> data = [x for x in range(10) if x%2 ==0]>>> data[0, 2, 4, 6, 8]>>> data = (x for x in range(100) if x%2 ==0)>>> data<generator object <genexpr> at 0x00DCE710>如果你的輸入序列很大,最好用生成器表達式,節省內存
字符串不能修改,大小也不能改變
任何沒有一個能修改現有的對象的方法,只是返回一個修改了的拷貝
到目前為止,已經有超過37個字符串方法
>>> s = 'Django is cool'>>> words = s.split()>>> words['Django', 'is', 'cool']>>> ' '.join(words)'Django is cool'>>> '::'.join(words)'Django::is::cool'>>> s.upper()'DJANGO IS COOL'>>> s'Django is cool'>>> s.upper().isupper()True>>> s.title()'Django Is Cool'>>> s.capitalize()'Django is cool'>>> s.count('o')3>>> s.find('go')4>>> s.find('xxxx')-1>>> s.startswith('Python')False>>> s.startswith('Django')True>>> s.replace('Django', 'Python')'Python is cool'>>>>>> mystr = u'This is Unicode'>>> mystru'This is Unicode'>>> print mystrThis is Unicode>>> filename = 'C:/temp/newfolder'>>> filename'C:/temp/newfolder'>>> print filenameC: empewfolder>>> filename = r'C:/temp/newfolder'>>> print filenameC:/temp/newfolder#為了保持一致,所有的正則表達式都要用raw指示符>>> regex = "/w+@/w+/./w+">>> print regex/w+@/w+/./w+>>> regex = r"/w+@/w+/./w+">>> print regex/w+@/w+/./w+通常Python字符串都只含有很少字符,不足以顯示更多的非英文字符。而Unicode是新型的字符集,擁有大量的編碼方式,不存在這個顯示。
>>> str = "中國">>> str'/xd6/xd0/xb9/xfa'>>> str = u"中國">>> stru'/u4e2d/u56fd'>>> str = r"中國">>> str'/xd6/xd0/xb9/xfa'>>> print str中國>>> str = u"中國">>> print str中國>>> str = "中國">>> print str中國>>> s = 'Django is cool'>>> '%s is number %d' % (s[:6], 1)'Django is number 1'>>> hi = '''hi... there'''>>> hi'hi/nthere'>>> print hihithere展示一個高級應用的實例
>>> xml = '''... <?xml version="1.0"?>... <request version="%.1f">... <Data>... <Payload>%s</Payload>... </Data>... </request>... '''>>> VERSION = 1.2>>> payload = 'super top-secret info'>>> print (xml %(VERSION, payload))<?xml version="1.0"?><request version="1.2"> <Data> <Payload>super top-secret info</Payload> </Data></request>表明上元組和列表只是用什么括號() []的區別,深層次的區別則要說道Python的對象模型。
列表允許改變值,元組不可以!(像字符串)所以元組沒有方法。
但是元組也不單單是一個只讀列表,元組的主要作用是作為參數傳遞給函數調用,或是從函數調用那里獲取參數時, 保護其內容不被外部接口修改。
所以元組在前臺的用武之地不大,但是在后臺卻很頻繁使用,例如Django的配置文件中的admin選項、URLconf規則、settings.py配置。
!!! 單個元素的元組要求在最后“必須”跟一個逗號,元組是逗號決定的,而不是小括號。
>>> a = ("one", "two")>>> a('one', 'two')>>> type(a)<type 'tuple'>>>> a[0]'one'>>> a = ('just-one')>>> a'just-one'>>> type(a)<type 'str'>>>> c = ('just-one',)>>> c('just-one',)>>> type(c)<type 'tuple'>>>> d = "just-one",>>> d('just-one',)>>> type(d)<type 'tuple'>>>> a=("one","two")>>> type(a)<type 'tuple'>>>> a('one', 'two')>>> len(a)2>>> max(a)'two'>>> sorted(a)['one', 'two']>>> sum(a)Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: unsupported Operand type(s) for +: 'int' and 'str'>>> any(a)True>>> zip(a, a)[('one', 'one'), ('two', 'two')]>>> b=list(a)>>> b['one', 'two']>>> c=str(a)>>> c"('one', 'two')">>> sum(b)Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: unsupported operand type(s) for +: 'int' and 'str'字典是Python中唯一的映射類型,可變的,無序的,大小可變的鍵值映射;別名散列表(hashes) 關聯數組
雖然語法跟序列相似,但是用鍵而不是下標來訪問元素;而且定義的話使用的花括號{ }
>>> book = {'title':'Python Web Dev', 'year':2008}>>> book{'year': 2008, 'title': 'Python Web Dev'}>>> type(book)<type 'dict'>>>> 'year' in bookTrue>>> book.get('pub')>>> book.get('pub', 'N/A')'N/A'>>> book['pub']Traceback (most recent call last): File "<stdin>", line 1, in <module>KeyError: 'pub'>>> book['pub']='Addision Wesley'>>> book['pub']'Addision Wesley'>>> book.get('pub', 'N/A')'Addision Wesley'>>> for key in book:... print key, ':', book[key] File "<stdin>", line 2 print key, ':', book[key] ^IndentationError: expected an indented block>>> for key in book:... print key, ':', book[key]...year : 2008pub : Addision Wesleytitle : Python Web Dev>>> book.setdefault('price', 100.00)100.0>>> book{'price': 100.0, 'year': 2008, 'pub': 'Addision Wesley', 'title': 'Python Web Dev'}>>> del book['price']>>> book{'year': 2008, 'pub': 'Addision Wesley', 'title': 'Python Web Dev'}>>> book['title']='Python Web Dev with Django'>>> book{'year': 2008, 'pub': 'Addision Wesley', 'title': 'Python Web Dev with Django'}>>> len(book)3Django 中類似字典的數據類型,Request對象和Response對象
list和字典dict是應用的最頻繁的數據類型data = raw_input("Enter y or n :")if data[0] == 'y': print "you enter y"elif data[0] == 'n' : print "you enter n"else print "invalid"for>>> i = 0>>> while i < 5:... print i... i += 1...01234更常用的是for循環,這個for循環更像是shell中的foreach,讓你專注于問題本身而不擔心計數變量。
for line in open('/tmp/some_file.txt') if 'error' in line: print line還記得列表推導式嗎?
data = [x for x in range(10) if x%2 ==0]
當然如果你還是要在循環的同時計數的話,可以使用內置函數enumerate(for循環自身沒辦法計數)
>>> for i, value in data:... print i...Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: 'int' object is not iterable>>> for i, value in data:... print value...Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: 'int' object is not iterable>>> for value in data:... print value...123abc3.14>>> data = (123, 'abc', 3.14)>>> for i, value in enumerate(data):... print i, value...0 1231 abc2 3.14>>>enumerate特別是在用到choices參數的地方
STATUS_CHOICES = enumerate(("solid", "liquid"))class IceCream(models.Model): falvor = models.CharField(max_length = 50) status = models.ItergerField(choices = STAUTS_CHOICES)在數據庫里, 你的IceCream的status值被保存為整數(0, 1, 2), 但是在Django的admin界面中顯示的確實是文字標簽。
這樣利用數據庫存儲的效率高,而且???當出現字符無法按照預想順序排序的時候也比較方便。
Python的try-except語句跟其他語言的try-catch結構相似;
運行時發生異常的話, 解釋器會找相應的處理語句handler;
要是在當前函數沒有找到,會將異常傳遞到上層函數;
如果到最外層全局main還是沒有找到,解釋器會退出,同時打印traceback以便讓用戶找出錯誤。
異常處理可以處理從簡單的單個異常到一系列的多個不同的異常類型。
try: f = open(filename, 'r')except IOError, e: return False, str(e)同一段處理語句也可以處理多個異常類型,只要放在一個元組中即可
try: process_some_data()except (TypeError, ValueError), e: print "Error: you provide invalid data", e或者為多個異常創建多個處理語句:(有點像swithc case break)
try: process_some_data()except (TypeError, ValueError), e: print "ERROR: invalid data", eexcept ArithmeticError, e: print "ERROR: some math error", eexcept Exceptioin, e: print "ERROR: invalid data", ePython還提供了一個 finally自居,無論錯誤是不是發生,這些代碼都必須運行,比如關閉文件,釋放鎖, 把數據庫連接返回給連接池。
try: get_mutex() do_some_stuff()finally: free_mutex()自Python2.5之后,try-finally 可以跟 except 一起使用。
try: get_mutex() do_some_stuff()except (IndexError, KeyError, AttributeError), e: log("ERORR:...")finally free_mutex()def foo(must_be_positive_int) if not isinstance(must_be_positive_int) raise TypeError("ERROR foo(): must pass in an integer") if must_be_positive_int < 1: raise ValueError("ERROR foo(): ...")more refert to : https://docs.python.org/2.7/library/exceptions.html
>>> f = open('test.txt', 'w')>>> f.write('foo/n')>>> f.write('bar/n')>>> f.close()>>> dir<built-in function dir>>>> f = open('test.txt', 'r')>>> for line in f:... print line.rstrip()...foobar>>> f = open('test.txt', 'r')>>> for line in f:... print line...foobar除了read 和 write 方法還有 readlines 和 writelines 方法,讓文件跟列表list打交道
>>> f = open('test.txt', 'r')>>> f.read()'foo/nbar/n'>>> f = open('test.txt', 'r')>>> f.readlines()['foo/n', 'bar/n']>>> f = open('test.txt', 'w')>>> f.writelines(['foo', 'bar'])>>> f = open('test.txt', 'r')>>> f.read()'foobar'重點)>>> def foo(x):... print x...>>> foo(123)123>>> import httplib>>> def check_web_server(host, port, path):... h = httplib.HTTPConnection(host, port)... h.request('GET', path)... resp = h.getresponse()... print 'HTTP Response:'... print ' status = ', resp.status... print ' reason = ', resp.reason... print 'HTTP Headers: '... for hdr in resp.getheaders():... print ' %s: %s' %hdr...>>> check_web_server('www.python.org', 80, '/')HTTP Response: status = 301 reason = Moved PermanentlyHTTP Headers: content-length: 0 via: 1.1 varnish x-cache: MISS accept-ranges: bytes strict-transport-security: max-age=63072000; includeSubDomains server: Varnish retry-after: 0 connection: close x-served-by: cache-ty67-TYO x-cache-hits: 0 location: https://www.python.org/ date: Wed, 24 Sep 2014 06:38:42 GMT>>> check_web_server('www.baidu.com', 80, '/')HTTP Response: status = 200 reason = OKHTTP Headers: content-length: 14613 bdqid: 0xa15e849b0000a0cc set-cookie: BAIDUID=C888FD3659C854691DC8B775D3D3C55E:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com, BDSVRTM=0; path=/ accept-ranges: bytes vary: Accept-Encoding bduserid: 0 server: BWS/1.1 last-modified: Wed, 03 Sep 2014 02:48:32 GMT connection: Keep-Alive pragma: no-cache cache-control: no-cache date: Wed, 24 Sep 2014 06:39:17 GMT p3p: CP=" OTI DSP COR IVA OUR IND COM " content-type: text/html bdpagetype: 1>>>調用的時候,我們需要記得函數定義中的參數順序:host, port, path
那如果沒有記得呢,可以用關鍵字參數,也是ok的
>>> check_web_server(path='/', port=80, host='www.baidu.com')定義函數的時候,Python同樣支持默認參數的定義
>>> def check_web_server(host, port=80, path='/')注意, 所有必須提供 的參數必須出現在可選參數之前,下面就是錯誤的
>>> def check_web_server(path, port=80, host) #INVALID危險因為列表和字典是可變的,當他們持續穿過多個函數調用時
>>> def func(arg=[]):... arg.append(1)... print arg...>>> func()[1]>>> func()[1, 1]>>> func()[1, 1, 1]>>> func()[1, 1, 1, 1]對象引用
在Python里面,你可把函數和方法當做和其他對象一樣的使用
只有當我們要調用函數的時候才會加上小括號(), 在把它當做變量或者對象傳來傳去的時候,只需要用函數的名字就好。
這將引用bar和調用bar()區分開來
>>> def bar():... print "bar"...>>> bar()bar>>> baz = bar>>> baz()bar>>>>>>>>> function_list = [bar, baz]>>> for function in function_list:... function()...barbar常見的例子是 URLconf 文件中設置 Django View
from django.conf.urls.defaults import *from myproject.myapp.views import listviewurlpatterns = patterns('', url(r'^list/', listview))這里的 listview 作為了一個包含了函數對象被直接使用,而不是一個包含了函數名字的字符串
另一個利用函數對象的地方時 model field 里的默認參數。
import datetimeclass DiaryEntry(models.Model): entry = models.TextField() date = models.DateField(default = datetime.date.today)這里的 datetime.date.today后面沒有() , 所以Django會在創建實例的時候才會調用函數而如果加上 (), 那么函數會在model定義的時候就調用,非我所想。
http://m.survivalescaperooms.com/ganiks
表達式和語句 expression & statement
python 代碼由 表達式和語句構成,并由python解釋器負責自行。
表達式是一個值,他的結果一定是一個python對象
lambda args:表達式舉個例子,對比下3個不同的處理方式:
這里有一個代表人物的復雜對象列表,希望按照姓氏排序
>>> list_of_people = [{'name':'ganiks', 'last_name':'liu'}, {'name':'henry', 'last_name':'ge'}]>>> list_of_people[{'last_name': 'liu', 'name': 'ganiks'}, {'last_name': 'ge', 'name': 'henry'}]>>> sorted(list_of_people, key = lambda person: person['last_name'])[{'last_name': 'ge', 'name': 'henry'}, {'last_name': 'liu', 'name': 'ganiks'}]#key期望的是一個函數對象,而lambda返回的正好是一個匿名函數#這個例子簡潔,目的明確sorted(list_of_people, key = lambda person: person.last_name)#這樣也是等價的#這個方便重復使用函數def get_last_name(person): return person.last_namesorted(list_of_people, key = get_last_name)#不建議使用這種,我們希望lambda是一次性的函數定義#不過,這進一步闡述了Python函數的First-Class的特性get_last_name = lambda person: person.last_namesorted(list_of_people, key = get_last_name)Django里面用到匿名函數的地方不多,但有個地方非常合適,即“認證裝飾器” authentication decorator,確認用戶是否有足夠權限訪問頁面;
將一個代表已登錄用戶的User對象傳遞給一個函數
@user_passes_test(lambda u: u.is_allowed_to_vote)def vote(request): """ Process a user's vote"""這個例子中調用了一個函數user_passes_test,接受了參數lambda u:u.is_allowed_to_vote之后返回 另一個“裝飾器”;也就是說裝飾器是 user_passes_test(lambda u:u.is_allowed_to_vote)
無論是函數調用或者聲明, *都代表元組(或者列表)出現, **代表字典出現。
函數調用里的 * ** 讓參數容器列表、元組、字典更優雅
def check_web_server(host, port, path)
check_web_server('localhost', 8000, '/damin/')
host_info = ('www.python.org', 80, '/')
checck_web_server(host_info[0], host_info[1], host_info[2])
用*讓代碼干凈和優雅
check_web_server(*host_info)
host_info = {'host': 'www.python.org', 'port': 80, 'path': '/'}
check_web_server(**host_info)
函數簽名里的 * ** 支持邊長參數 varargs
在函數定義里使用變長參數時,參數的順序是要求的;先是必須出現的參數,然后是由默認值的參數,最后才是變長參數
def check_web_server(host, port, path, *args, **args)這個函數必須至少接受初始的三個參數,但是也能接受隨后任何數目的參數或是關鍵字參數
還有一種全部由變長參數組成的所謂通用的Python方法簽名
def f(*args, **kwargs):#正確調用f()f(a, b, c)f(a, b, foo=c, bar=d)Django數據庫API查詢經常包含關鍵字參數,比如:
bob_stories = Story.objects.filter( title_contains = "bob", subtitle_contains = "bob", text_contains = "bob", byline_contains = "bob")#用變長參數字典來讓參數獨立bobargs = { 'title_contains': "bob", 'subtitle_contains': "bob", 'text_contains': "bob", 'byline_contain': "bob"}bob_stories = Story.objects.filter(**bobargs)#動態創建字典bobargs = dict((f + '__contains', 'bob') for f in ('title', 'subtitle', 'text', 'byline'))bob_stories = Story.objects.filter(**bobargs)裝飾器是一種讓你能改變或者說“裝飾” 函數行為的機制,能讓函數執行一些和原本設計不同,或是在原有基礎上額外的操作。
裝飾器也可以說是對函數的一個包裝,這些額外的任務包括寫日志、計時、過濾
python 里的一個被包裹或者被裝飾的函數(對象)通常會被重新賦值給原來的名字
@decodef foo(): pass等價于
foo = deco(foo)再舉個例子記錄下函數調用的發生:
>>> def log(func):... def wrappedFunc():... print "**** %s() called" % func.__name__... return func()... return wrappedFunc...>>> @log... def foo():... print "inside foo()"...>>> foo()**** foo() calledinside foo()再看看之前的一個例子
將一個代表已登錄用戶的User對象傳遞給一個函數
@user_passes_test(lambda u: u.is_allowed_to_vote)def vote(request): """ Process a user's vote"""這個例子中調用了一個函數user_passes_test,接受了參數lambda u:u.is_allowed_to_vote之后返回 另一個“裝飾器”;也就是說裝飾器是 user_passes_test(lambda u:u.is_allowed_to_vote)
它的邏輯是這樣的:
@decomaker(deco_args)def foo(): pass等價于
foo = decomaker(deco_args)(foo)再比如應用多個裝飾器:
@deco1(deco_args@)@deco2def foo(): pass為什么要用裝飾器呢?
本質就是包裹函數,接受對象,修改并重新賦值給原來的變量;
OOP的主要目標是在代碼和顯示問題之間提供一個合乎邏輯的映射關系,并且鼓勵代碼的重用和共享。
class AddressBookEntry(object): version = 0.1 def __init__(self, name, phone): self.name = name self.phone = phone def update_phone(self, phone): self.phone = phone靜態成員屬于整個類的變了,可以再所有的實例之間共享self對象john = AddressBookEntry('Jone Doe', '400999999')jane = AddressBookEntry('Jane Dey', '300293202')>>> john.phone'400999999'>>> john.tattoo = 'Mom'python中實例化不需要像其他語言一樣new對象,而是可以直接調用函數一樣即可
python用的是初始化程序initializer而不是構造函數 constructor,所以名字也是__init__
在實例化一個對象的時候,不用傳入self對象,python會自動為你傳入self對象
PS: python還支持直接創造沒有在類定義中聲明的對象,比如上面例子中的tattoo
class EmployeeAddressBookEntry(AddressBookEntry): def __init(self, name, phone, id, social): AddressBookEntry.__init__(self, name, phone) self.empid = id self.ssn = social嵌套類的概念類似于創建裝飾器的“嵌套函數”,即在類的內部定義類
class MyClass(object): class InnerClass: passform django.db import modelsfrom django.contrib import adminclass BlogPost(models.Model): title = models.CharField(max_length = 150) body = models.TextField() timestamp = models.DateTimeField()class Meta: ordering = ('-timestamp',)Django的數據model是從Django內置類 django.db.models.Model 繼承而來的子類
re.search 返回一個匹配對象Match,隨后可以用這個對象的 group 或者 groups
方法獲取匹配的模式;匹配失敗時,返回的是None
額,這里用“匹配”有點不準確,確切的說是“搜索”,而“匹配”指的是整個字符串都要符合模式的描述
>>> import re>>> m = re.search(r'foo', 'seafood')>>> print m<_sre.SRE_Match object at 0x00DAE4B8>>>> m.group<built-in method group of _sre.SRE_Match object at 0x00DAE4B8>>>> m.group()'foo'>>> m = re.search(r'bar', 'seafood')>>> print mNone>>>>>>>>> import re>>> m = re.match(r'foo', 'seafood')>>> if m is not None: print m.group()...>>> print mNone>>> if m is not None: print m.groups()...>>> print mNone>>> m = re.search(r'foo', 'seafood')>>> if m is not None: print m.group()...foo>>> if m is not None: print m.groups()...()>>> if m is not None: print m.group()...fooimport randomprint random.choice(range(10))from random import choiceprint choice(range(10))python有導入模塊和加載模塊之分,一個模塊可以被導入N次,但是只會被加載一次,無需擔心額外消耗內存的問題。
package是Python在文件系統上發布一組模塊的一種方式,通過 __init__.py 實現
Phone/ __init__.py util.py Voicedata/ __init__.py posts.py Isdn.py Fax __init__.py G3.py Mobile __init__.py Anolog.py Digital.py__init.__.py告訴Python解釋器這些目錄下的文件應該被當做是一個子package而不是普通文件,一般它們都是空文件,當然也可以做一些初始化的工作。
import Phone.Mobile.AnalogPhone.Mobile.Anolog.dial()import Phone.Mobile.Analog as pmapma.dial()在Python中跟一般不這么說,而是說 對象時可變或者不可變 mutable or immutable
對象有 類型,標示符,值 三個屬性, 如果值 是可變的,那么這個對象就是可變的;
前面語法其實已經介紹過了,標量scalar類型(整數浮點數復數)、str、unicode字符串、元組是不可變的;其他的列表、字典、類、類實例都是可變的。
可變性是Python中重要的概念,這也解釋了為什么Python要提供兩種列表, list 和 tuple
如果你調用的函數有任何修改一個可變對象的行為的話,通常它都是直接修改的,即直接修改數據結構而不是返回一個拷貝(返回None)
比如 list.sort, list.reverse, list.extend, dict.update都是直接修改
深拷貝和淺拷貝 deep copy & shallow copy
>>> from copy import deepcopy>>> mylist2 = deepcopy(mylist)>>> mylist2[1, 'a', ['foo', 'bar']]>>> mylist2[0] = 2>>> mylist2[2][0] = 'biz'>>> mylist2[2, 'a', ['biz', 'bar']]>>> mylist[1, 'a', ['foo', 'bar']]>>> mylist2 = list(mylist)>>> mylist2[0] = 2>>> mylist2[2][0] = 'biz'>>> mylist[1, 'a', ['biz', 'bar']]>>> mylist2[2, 'a', ['biz', 'bar']]上面的例子中分別是一個深拷貝和淺拷貝的例子,先看看淺拷貝:
mylist中前兩個對象時整數和字符串,所以mylist2會得到2個全新的整數和字符串對象,所以1=>2
但是mylist的第三個對象時列表,列表時可變的,所以mylist2得到的只是一個引用,所以
‘foo'=>'biz'影響到了mylist本身
而深拷貝就不會了, 1=>2 'foo'=>'biz' 都不會影響mylist
深拷貝通常是地柜的(如果循環引用會有問題),而且不是所有的對象都是可以深拷貝的。
雖然Python是OOP的語言,但是沒有顯式的構造函數的概念,沒有 new 關鍵字,沒有
真的實例化你的類。
python會為你創建實例并調用初始化程序,在你的對象創造出來之后,Python將它返回給你之前調用的第一個方法__init__
>>> from time import ctime>>> class MyClass(object):... def __init__(self, date):... print "instance created at: ", date...>>> m = MyClass(ctime())instance created at: Sat Sep 27 10:31:22 2014>>>另外python也沒有析構函數來銷毀對象,只要讓它離開作用域就行了,會被自動垃圾回收。
不過,你可以在 python對象中定義一個 __del__方法來當做析構函數,可以用 del my_object來顯式的銷毀對象。
動態實例屬性Python的另一個重要的特性是動態實例屬性 dynamic instance attribute
實例的屬性可以動態分配,
即使在類定義已經完成甚至是已經創建里實例,還是可以給你的實例添加一個之前沒有提到過的屬性
創建文檔字符串(docstring)
C:/Documents and Settings/ganiks.liu/Desktop>vim foo.py"""foo.py --sample module demostrating documentation strings """class Foo(object): """ Foo() - empty class ... tobe developed """def bar(x): """bar(x) - function docstring for bart, prints out its arg 'x'""" print xC:/Documents and Settings/ganiks.liu/Desktop>pythonPython 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32Type "help", "copyright", "credits" or "license" for more information.>>> import foo>>> foo.__doc__'foo.py --sample module demostrating documentation strings '>>> foo.Foo.__doc__' Foo() - empty class ... tobe developed '>>> foo.bar.__doc__"bar(x) - function docstring for bart, prints out its arg 'x'">>> help(foo)Help on module foo:NAME foo - foo.py --sample module demostrating documentation stringsFILE c:/documents and settings/ganiks.liu/desktop/foo.pyCLASSES __builtin__.object Foo class Foo(__builtin__.object) | Foo() - empty class ... tobe developed | | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined)FUNCTIONS bar(x) bar(x) - function docstring for bart, prints out its arg 'x'
|
新聞熱點
疑難解答