中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
python筆記

前言

先扯一點(diǎn)背景知識(shí)

PEP8(Python Enhancement Proposal)是一份python的編碼規(guī)范,鏈接:http://www.python.org/dev/peps/pep-0008/

在這份編碼規(guī)范中的“命名規(guī)范-命名風(fēng)格”這一節(jié)的最后,提到了對(duì)幾種使用前置和后置下劃線的,對(duì)變量的比較特殊的命名方式:

  • 單下劃線開頭:弱內(nèi)部使用標(biāo)識(shí),無法被from M import *所引用
  • 單下劃線結(jié)尾:避免和python關(guān)鍵字沖突,可以加個(gè)后置下劃線
  • 雙下劃線開頭:類成員變量中的私有變量,
  • 雙下劃線開頭,雙下劃線結(jié)尾:這是magic對(duì)象或?qū)傩缘拿?,永遠(yuǎn)不要將這樣的命名方式應(yīng)用于自己的變量和函數(shù)

本文主要關(guān)注正是以上第四種--python自動(dòng)在用戶命名空間創(chuàng)建的magic變量

1、__name__變量

__name__屬性是直接內(nèi)置在.py文件中的。

  • 如果直接執(zhí)行.py文件,__name__將被設(shè)置為__main__。
  • 如果.py文件是被import,__name__將被設(shè)置為.py文件的名字

這個(gè)屬性經(jīng)常用來當(dāng)做一個(gè)使用模式的標(biāo)識(shí):

#a.pyprint 'a function'if __name__=='__main__': print 'a test'------------------------------#b.pyimport a

如果執(zhí)行python a.py將打印出兩行內(nèi)容,執(zhí)行python b.py只會(huì)打印出'a function'。一般可以把只針對(duì)a.py的測(cè)試代碼寫在if __name__=='__main__',因?yàn)槿绻鸻.py被其他的腳本import之后,這部分代碼將不會(huì)被執(zhí)行??梢院馨踩膶?duì)a.py進(jìn)行單獨(dú)的測(cè)試。

2、__file__變量

__file__可以用來獲取python腳本的“路徑+腳本名稱”,這可能是一個(gè)相對(duì)路徑也可能是一個(gè)絕對(duì)路徑,取決按照什么路徑來執(zhí)行的腳本,一般來說__file__變量和os.path配合,可以用來獲取python腳本的絕對(duì)路徑:

#a.pyimport osprint os.path.realpath(__file__)out>>E:\Eclipse_workspace\python_learn\a.py

3、__import__函數(shù)

python導(dǎo)入模塊時(shí),一般使用import,而import語句其實(shí)也是調(diào)用builtin函數(shù):__import__()實(shí)現(xiàn)的導(dǎo)入,直接使用__import__比較少見,除非導(dǎo)入的模塊是不確定的,需要在運(yùn)行時(shí)才能確定導(dǎo)入哪些模塊,可以使用__import__,默認(rèn)接收需要導(dǎo)入的模塊名的字符串:

#a.pydef f1(): print 'f1'def f2(): print 'f2'#b.pymodel=__import__('a')model.f1()model.f2()

在memfs的測(cè)試中,我的每一個(gè)測(cè)試case就是一個(gè)獨(dú)立的.py文件,在確定需要測(cè)試哪些case后,在運(yùn)行時(shí)才‘動(dòng)態(tài)的’去import相應(yīng)的case,就是通過__import__來實(shí)現(xiàn)的。

4、__str__函數(shù)

__str__是一個(gè)比較常用的內(nèi)置函數(shù),在定義類的時(shí)候經(jīng)常使用,__str__函數(shù)返回一個(gè)字符串,這個(gè)字符串就是此對(duì)象被print時(shí)顯示的內(nèi)容,(如果不定義這個(gè)函數(shù),將會(huì)顯示默認(rèn)的格式:<__main__.A object at 0x0000000001FB7C50>):

#a.pyimport datetimeimport osclass A(object):    def __str__(self):        #返回當(dāng)前的日期        return str(datetime.datetime.now())a=A()print atime.sleep(1)#每次打印A()的對(duì)象,都返回當(dāng)前的時(shí)間print aout>>2015-06-25 15:01:01.573000out>>2015-06-25 15:01:02.573000

這個(gè)函數(shù)在django的model類中如果定義的話,print一條數(shù)據(jù)庫中的數(shù)據(jù),可以指定顯示任何的值:

class Question(models.Model):#定義一個(gè)數(shù)據(jù)庫表,其中包含question_id和question_text#....def __str__(self): #只想顯示question_text return self.question_text

注:在python3.x中str被廢棄,使用unicode

5、__init__對(duì)象函數(shù)

__init__比較常見,是對(duì)象的初始化函數(shù),例子如下:

#a.pyclass A(object):    passclass B(A):    #B類繼承自A,如果要重寫__init__,需要先調(diào)用父類的__init__    def __init__(self,*args):        super(B,self).__init__(*args)

6、__new__對(duì)象函數(shù)

__new__()函數(shù)是類創(chuàng)建對(duì)象時(shí)調(diào)用的內(nèi)置函數(shù),必須返回一個(gè)生成的對(duì)象,__new__()函數(shù)在__init__()函數(shù)之前執(zhí)行。一般來說沒有比較重載這個(gè)函數(shù),除非需要更改new對(duì)象的流程,有一種場(chǎng)景“單例模式”要求只能存在一個(gè)class A的對(duì)象,如果重復(fù)創(chuàng)建,那么返回的已經(jīng)創(chuàng)建過的對(duì)象的引用。可以這樣使用__new__函數(shù):

a.pyclass A(object): def __new__(cls): if not '_instance' in vars(cls): cls._instance=super(A,cls).__new__(cls) return cls._instancea=A()b=A()print id(a)==id(b)out>>True

可以看出,a和b其實(shí)引用了同一個(gè)對(duì)象

7、__class__對(duì)象變量

instance.__class__表示這個(gè)對(duì)象的類對(duì)象,我們知道在python中,類也是一個(gè)對(duì)象(好理解么),例:

#a.pyclass A(object):    passa=A()B=a.__class__b=B()print type(b)out>><class '__main__.A'>

可以看出,a是A類的一個(gè)對(duì)象,a.__class__就是A類,將這個(gè)類賦值給B,使用B()又可以創(chuàng)建出一個(gè)對(duì)象b,這個(gè)對(duì)象b也是A類的對(duì)象,(暈了么?),這個(gè)__class__有什么卵用呢?下面的例子就可以用到

8、__add__對(duì)象函數(shù)

這其實(shí)是一類函數(shù),包括__sub__,__mul__,__mod__,__pow__,__xor__,這些函數(shù)都是對(duì)加、減、乘、除、乘方、異或、等運(yùn)算的重載,是我們自定義的對(duì)象可以具備運(yùn)算功能:

#a.pyclass A(object): def __init__(self,v): self.v=v def __add__(self,other): #創(chuàng)建創(chuàng)建一個(gè)新的對(duì)象 x=self.__class__(self.v+2*other.v) return xa=A(1)b=A(2)c=a+bprint c.vouot>>5

這樣我們就定義了一個(gè)加法操作1+2=1+2*2=5

9、__doc__文檔字符串

python建議在定義一個(gè)類、模塊、函數(shù)的時(shí)候定義一段說明文字,例子如下:

#c.py'''script c's doc'''class A(object):    '''    class A's doc    '''    passdef B():    '''    function B's doc    '''    passprint __doc__print A.__doc__print B.__doc__out>>script c's docout>>class A's docout>>function B's doc

調(diào)用別的模塊、函數(shù)的時(shí)候如果不清楚使用方法,也可以直接查看doc文檔字符串

10、__iter__和next函數(shù)

凡是可以被for....in的循環(huán)調(diào)用的對(duì)象,我們稱之為可以被迭代的對(duì)象,list,str,tuple都可以被迭代,它們都實(shí)現(xiàn)了內(nèi)部的迭代器函數(shù),比如說list,tuple,字符串這些數(shù)據(jù)結(jié)構(gòu)的迭代器如下:

a=[1,2,3,4]b=('i',1,[1,2,3])print a.__iter__()print b.__iter__()out>><listiterator object at 0x0000000001CC7C50>out>><tupleiterator object at 0x0000000001CC7B00>

如果我們要實(shí)現(xiàn)一個(gè)我們自己的迭代器對(duì)象,那么我們必須實(shí)現(xiàn)兩個(gè)默認(rèn)的方法:__iter__和next。

__iter__()函數(shù)將會(huì)返回一個(gè)迭代器對(duì)象,next()函數(shù)每次被調(diào)用都返回一個(gè)值,如果迭代完畢,則raise一個(gè)StopIteration的錯(cuò)誤,用來終止迭代。下面的例子將實(shí)現(xiàn)一個(gè)可以迭代的對(duì)象,輸出a~z的26個(gè)字母,該對(duì)象接收一個(gè)int參數(shù)用來表示輸出字母的數(shù)量,如果該參數(shù)超過字母表的長(zhǎng)度,則循環(huán)從‘a(chǎn)-z’再次進(jìn)行循環(huán)輸出:

import randomclass A(object):    def __init__(self,n):        self.stop=n        self.value=0        #字母列表        self.alph=[chr(i) for i in range(97,123)]    def __iter__(self):        return self    def next(self):        #如果超過長(zhǎng)度超過26則重置        if self.value==len(self.alph):            self.value=0            self.stop=self.stop-len(self.alph)        #最終,已完成n個(gè)字符的輸出,則結(jié)束迭代        if self.value>self.stop:            raise StopIteration            x=self.alph[self.value]        self.value+=1        return xfor i in A(1000):    print i,out>>a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k .....

11、__dict__、__slot__和__all__

這三個(gè)變量有一些關(guān)系,__dict__在類和對(duì)象中都存在,它是一個(gè)包含變量名和變量的字典,見以下的例子:

#a.pyclass A(object): c=3 d=4 def __init__(self): self.a=1 self.b=2 def func(self): passprint A().__dict__print A.__dict__out>>{'a': 1, 'b': 2}out>>{'__module__': '__main__', 'd': 4, 'c': 3, 'func': <function func at 0x00000000021F2BA8>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None, '__init__': <function __init__ at 0x00000000021F2AC8>}

一個(gè)對(duì)象的__dict__只包含self定義的變量,而一個(gè)類的__dict__包含了類里面的函數(shù)(func函數(shù))、類變量,以及很多隱性的變量,包括__dict__變量本身也是隱性的。

__slot__變量的用法理解起來比較要難一點(diǎn),正常的情況下,我們實(shí)例化一個(gè)對(duì)象,可以給這個(gè)對(duì)象增加任意的成員變量,即使不在類里面定義的變量都可以,如下:

#a.pyclass A(object):    def __init__(self):        self.a=1        self.b=2a=A()#給a增加一個(gè)x變量a.x=1#也可以給a增加一個(gè)匿名函數(shù)a.y=lambda x,y:x*yprint a.xprint a.y(3,5)out>>1out>>15

如果我們想限制一下對(duì)象綁定的變量,我們可以在類定義的時(shí)候增加一個(gè)slots變量,這個(gè)變量是一個(gè)字符串的元組,例子如下:

class A(object): __slots__=('a','b','x') def __init__(self): self.a=1 self.b=2 pass #__slots__=('a','b',) def func(self): passa=A()a.x=1#執(zhí)行到a.y時(shí)會(huì)報(bào)錯(cuò):AttributeError: 'A' object has no attribute 'y'a.y=lambda x,y:x*yprint a.y(3,5)

__all__變量是一個(gè)字符串列表,它定義了每一個(gè)模塊會(huì)被from module_name import *這樣的語句可以被import的內(nèi)容(變量,類,函數(shù))

#a.py 不定義__all__class A(object):    def __init__(self):        self.a=1        self.b=2    def func(self):        passdef B():    passc=10#b.pyfrom a import *print Aprint Bprint cout>><class 'learn_draft.A'>out>><function B at 0x00000000021D1438>out>>10

如果在a.py中定義__all__=['A','c'],則B函數(shù)對(duì)于b.py來說是不可見的。

12、__hash__

哈希函數(shù),在python中的對(duì)象有一個(gè)hashable(可哈希)的概念,對(duì)于數(shù)字、字符串、元組來說,是不可變的,也就是可哈希的,因此這些對(duì)象也可以作為字典的key值。另外,列表、字典等,是可變對(duì)象,因此也就是不可哈希的,也就不能作為字典的key值。是否可哈希,可以調(diào)用內(nèi)置函數(shù)hash()進(jìn)行計(jì)算,hash()函數(shù)返回計(jì)算的到的hash值。

  • 完全相同的變量,調(diào)用哈希算法的到的hash值一定是相同的

當(dāng)然一般來說,我們不會(huì)去重新定義一個(gè)對(duì)象的__hash__函數(shù),除非我們想實(shí)現(xiàn)一個(gè)自定義的需求,在stackoverflow有人提出這樣一個(gè)需求,需要判斷有相同詞頻的字符串是相等的,也就是說“abb”和“bab”這樣的字符串是相等的,這個(gè)時(shí)候我們可以繼承字符串類,然后重寫哈希函數(shù),如下:

import collectionsclass FrequencyString(str): @property def normalized(self): try: return self._normalized except AttributeError: self._normalized = normalized = ''.join(sorted(collections.Counter(self).elements())) return normalized def __eq__(self, other): return self.normalized == other.normalized def __hash__(self): return hash(self.normalized)

13、__getattr__和__setattr__,__delattr__對(duì)象函數(shù)

先介紹兩個(gè)內(nèi)置函數(shù),getattr()和setattr(),使用這兩個(gè)函數(shù)可以獲取對(duì)象的屬性,或者給對(duì)象的屬性賦值:

#a.pyclass A(object):    def __init__(self):        self.a=1        self.b=2a=A()setattr(a,'a',3)print a.aprint getattr(a,'b')out>>3out>>2

其實(shí)使用這兩個(gè)函數(shù)和直接訪問a.a,a.b沒有任何區(qū)別,但好處是setattr和getattr接受兩個(gè)字符串去確定訪問對(duì)象a的哪一個(gè)屬性,和__import__一樣,可以在運(yùn)行時(shí)在決定去訪問對(duì)象變量的名字,在實(shí)際工作中經(jīng)常會(huì)使用這兩個(gè)函數(shù)。

__getattr__()這個(gè)函數(shù)是在訪問對(duì)象不存在的成員變量是才會(huì)訪問的,見下面的例子:

class A(object): def __init__(self): self.a=1 self.b=2 def func(self): pass def __getattr__(self,name): print 'getattr' return self.aa=A()print a.dout>>getattrout>>1

在調(diào)用a.d時(shí),d不是a的成員變量,則python會(huì)去查找對(duì)象是否存在__getattr__()函數(shù),如果存在,則返回__getattr__()函數(shù)的返回值,我們這里返回的是self.a的值1。

由于__getattr__()的特性,我們可以將__getattr__()設(shè)計(jì)成一個(gè)公共的接口函數(shù),在autotest的proxy.py中就看到了這樣的用法:

class ServiceProxy(object):def __init__(self, serviceURL, serviceName=None, headers=None):    self.__serviceURL = serviceURL    self.__serviceName = serviceName    self.__headers = headers or {}def __getattr__(self, name):    if self.__serviceName is not None:        name = '%s.%s' % (self.__serviceName, name)    return ServiceProxy(self.__serviceURL, name, self.__headers)#調(diào)用的時(shí)候,op是執(zhí)行的特定操作的字符串,op傳入__getattr__將會(huì)把ServiceProxy對(duì)象重新的內(nèi)部變量重新賦值,然后返回一個(gè)更新之后的對(duì)象function = getattr(self.proxy, op)

__setattr__和__getattr__不一樣,對(duì)象的所有屬性賦值,都會(huì)經(jīng)過__setattr__()函數(shù),看下面的例子:

class A(object): def __init__(self): self.a=1 self.b=2 def func(self): pass def __getattr__(self,name): print 'getattr' return self.a def __setattr__(self, name, value): print 'setattr %s' % name if name == 'f': return object.__setattr__(self,name,value+1000) else: return object.__setattr__(self, name, value)a=A()a.f=1000print a.fout>>setattr aout>>setattr bout>>setattr fout>>2000

從輸出可以看到init函數(shù)的self.a和self.b的賦值也經(jīng)過了__setattr__,而且在賦值的時(shí)候我們自定義了一個(gè)if邏輯,如果name是‘f’,那么value會(huì)增加1000,最終的a.f是2000

__delattr__不舉例了,刪除一個(gè)對(duì)象屬性用的。

14、__call__對(duì)象函數(shù)

如果一個(gè)對(duì)象實(shí)現(xiàn)了__call__()函數(shù),那么這個(gè)對(duì)象可以認(rèn)為是一個(gè)函數(shù)對(duì)象,可以使用加括號(hào)的方法來調(diào)用,見下面例子:

class A(object):    def __init__(self):        self.li=['a','b','c','d']    def func(self):        pass    def __call__(self,n):        #返回li列表的第n個(gè)元素        return self.li[n]a=A()#a可以當(dāng)做函數(shù)一樣調(diào)用print a(0),a(1),a(2)out>>a b c

在實(shí)際工作中__call__函數(shù)非常有用,可以把一個(gè)對(duì)象變成callable的對(duì)象

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Python 2 和 Python 3 主要區(qū)別有哪些(一)
Python 3 入門,看這篇就夠了!數(shù)萬字長(zhǎng)文!保證你肯定能學(xué)會(huì)!
Python數(shù)據(jù)分析系列文章之Python基礎(chǔ)
風(fēng)變編程筆記(一)-Python基礎(chǔ)語法
Python 程序設(shè)計(jì)(第二版)董付國
Python知識(shí)點(diǎn)匯總
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服