涉及到狀態(tài)保存,可以使用函子(書(shū)上這么翻譯的,不曉得其他人是不是也這樣叫),給你個(gè)例子,你比對(duì)著改。如果不懂,自己再延這個(gè)方向去查看資料。
創(chuàng)新互聯(lián)主營(yíng)睢寧縣網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,app開(kāi)發(fā)定制,睢寧縣h5成都小程序開(kāi)發(fā)搭建,睢寧縣網(wǎng)站營(yíng)銷推廣歡迎睢寧縣等地區(qū)企業(yè)咨詢
class?Strip:
def?__init__(self,?characters):?#初始化,將需要保留的狀態(tài)信息存起來(lái)
self.characters?=?characters
def?__call__(self,?string):?#創(chuàng)建的函子被使用時(shí),自動(dòng)調(diào)用__call__
return?string.strip(self.characters)
#下面是使用方法,兩個(gè)語(yǔ)句是密切銜接的。
strip_punctution?=?Strip(',;:.!?')?#字符串參數(shù)將被__init__吃進(jìn)去,并且保留在class中,
#相當(dāng)于一種狀態(tài)保存的方法,在你的例子中,你可以將用戶表達(dá)式通過(guò)這種方式保存起來(lái)
strip_punctution('hello?world!')?#return?'hello?world',他的功能是剝離characters
#字符串中出現(xiàn)的字符,此處把感嘆號(hào)去掉了,
#這就是函子典型的使用方法,class中的__call__函數(shù)被自動(dòng)調(diào)用,在你的
#例子中,你可以通過(guò)這樣的方式調(diào)用函數(shù),就不用每次重新輸入表達(dá)式了。
params
就是(5, 5)
(5,) * 2 ,就是2個(gè)5的元組,乘號(hào)可以理解成相加。"*" * 30就是30個(gè)“*"的字符串
*params作為參數(shù),前面的*號(hào)就是把params元組分解成元素的意思,這樣就分開(kāi)成為2個(gè)參數(shù)了。實(shí)際上傳遞給了x,y
于是就執(zhí)行了power(5,5)
其實(shí)安裝python包會(huì)自帶一個(gè)有問(wèn)號(hào)標(biāo)示“?”的"Python Manuals"可以仔細(xì)閱讀一下,也可作幫助文檔的。
介紹Python的內(nèi)建函數(shù)和異常.許多內(nèi)建函數(shù)的細(xì)節(jié)及特性可以在這里找到.
內(nèi)建函數(shù)
本節(jié)介紹的函數(shù)在解釋器中總是可用的,他們被包含在 __builtin__ 模塊里.另外每個(gè)模塊的 __builtins__ 屬性經(jīng)常指的是這個(gè)模塊(除了當(dāng)在restricted execution環(huán)境下運(yùn)行時(shí)).
_(下劃線)
默認(rèn)情況下,變量 _ 用于在交互模式下表示最近一個(gè)表達(dá)式的運(yùn)行結(jié)果.
參閱 sys.displayhook (118)
__import__(name [, globals [, locals [, fromlist]]])
import語(yǔ)句通過(guò)調(diào)用這個(gè)函數(shù)來(lái)導(dǎo)入模塊. name是包含模塊名字的字符串, globals是一個(gè)可選的定義全局名稱空間的字典, locals是定義局部名稱空間的字典, fromlist是from語(yǔ)句目標(biāo)的列表.例如, import spam語(yǔ)句會(huì)調(diào)用__import__('spam', globals(), locals(), []) ,而from spam import foo 語(yǔ)句會(huì)調(diào)用 __import__('spam', globals(), locals(), ['foo']). 如果模塊名在包名字之后(如foo.bar)而且fromlist為空時(shí),就返回對(duì)應(yīng)的模塊對(duì)象.如果fromlist不為空,則只會(huì)返回最頂級(jí)的包.
這個(gè)函數(shù)是一個(gè)低等級(jí)的模塊載入接口.它并不執(zhí)行import語(yǔ)句的所有步驟(通常情況下局部名稱空間并不會(huì)隨模塊中包含對(duì)象的名稱引用的改變而改變.這個(gè)函數(shù)可以由用戶來(lái)重新定義,這樣為import語(yǔ)句加入新的行為.默認(rèn)的執(zhí)行并不會(huì)檢查locals參數(shù),而globals只用于決定包的內(nèi)容(這些參數(shù)可以使 __import__()能夠完整地訪問(wèn)全局和局部名稱空間)
abs(x)
返回x的絕對(duì)值
apply(func [, args [, keywords]])
對(duì)可調(diào)用對(duì)象func執(zhí)行函數(shù)調(diào)用. args是一個(gè)包含固定位置參數(shù)的元組, keywords是包含關(guān)鍵參數(shù)的字典. apply()函數(shù)也可以寫(xiě)做func(*args ,**keywords ).
buffer(sequence [, offset [, size]])
創(chuàng)建一個(gè)新的緩沖器對(duì)象.緩沖器通常是一個(gè)序列(如字符串)的字節(jié)導(dǎo)向序列.緩沖器和字符串在許多地方是相同的,但是它不支持字符串方法,而且也不能使用string模塊的函數(shù).
callable(object)
當(dāng)object為可調(diào)用對(duì)象時(shí)返回True,否則返回False
chr(i)
將一個(gè)0到255的整數(shù)轉(zhuǎn)換為一個(gè)字符.
cmp(x,y)
比較x和y. x y返回負(fù)數(shù); x== y返回零; x y返回整數(shù).它可以比較任意兩個(gè)對(duì)象并返回結(jié)果,即使有時(shí)候?qū)ο蟮谋容^豪無(wú)意義(例如比較文件對(duì)象).在某些環(huán)境下,這樣的比較會(huì)引發(fā)異常.
coerce(x,y)
將x和y值轉(zhuǎn)換為同一個(gè)數(shù)值類型并作為一個(gè)元組返回.(第三章,類型和對(duì)象)
compile(string, filename, kind)
使用exec()或eval()將字符串編譯為代碼對(duì)象. filename is a string containing the name of the file in which the string was defined. kind為'exec'時(shí)代表一個(gè)表達(dá)式的序列, 'eval'代表一個(gè)表達(dá)式, 'single'代表一個(gè)運(yùn)行語(yǔ)句.
complex(real [, imag])
創(chuàng)建一個(gè)復(fù)數(shù)
delattr(object, attr)
刪除對(duì)象的一個(gè)屬性, attr是一個(gè)字符串.與 del object.attr相同
dir([object])
返回包含屬性名稱的列表.它們來(lái)自對(duì)象的 __dict__, __methods__,以及 __members__ 屬性.如果沒(méi)有傳遞給它參數(shù),則會(huì)返回當(dāng)前的local symbol table
divmod(a,b)
返回一個(gè)包含商和余數(shù)的元組.對(duì)于整數(shù),將返回(a / b , a % b ),對(duì)于浮點(diǎn)數(shù),將返回(math.floor(a / b ), a % b )
eval(expr [, globals [, locals]])
計(jì)算一個(gè)表達(dá)式的值. expr是一個(gè)字符串或由compile()創(chuàng)建的一個(gè)代碼對(duì)象. globals和locals為操作定義的全局和局部名稱空間,當(dāng)省略時(shí),表達(dá)式將在調(diào)用時(shí)的名稱空間計(jì)算.
execfile(filename [, globals [, locals]])
運(yùn)行文件filename中的語(yǔ)句. globals和locals定義了文件運(yùn)行的全局和局部名稱空間,當(dāng)省略時(shí),文件將在調(diào)用時(shí)的名稱空間運(yùn)行.這個(gè)函數(shù)不能在一個(gè)函數(shù)主體里使用,因?yàn)樗c內(nèi)嵌范圍不相容.
filter(function, list)
使用func()函數(shù)來(lái)過(guò)濾s中的元素.使func返回值為false的元素被丟棄,其它的存入filter函數(shù)返回的列表中.如果function是None,則list中值為False的元素就被刪除.
float(x)
將x轉(zhuǎn)換為浮點(diǎn)數(shù)
getattr(object, name [, default])
返回一個(gè)對(duì)象的屬性. name是一個(gè)字符串. default是一個(gè)可選的值,代表當(dāng)沒(méi)有這個(gè)屬性時(shí)返回的值. 與 object.name 結(jié)果相同
globals()
返回一個(gè)與全局名稱空間對(duì)應(yīng)的字典
hasattr(object, name)
返回object是否有name屬性,布爾值
hash(object)
返回一個(gè)對(duì)象的整數(shù)哈希值(如果可能).兩個(gè)相等對(duì)象的哈希值是相同的.模塊沒(méi)有定義一個(gè)哈希值.
hex(x)
將一個(gè)整數(shù)或長(zhǎng)整數(shù)轉(zhuǎn)換為一個(gè)十六進(jìn)制的字符串
id(object)
返回一個(gè)對(duì)象的整數(shù)id
input([prompt])
相當(dāng)于eval(raw_input(prompt ))
int(x [, base])
將一個(gè)數(shù)字或字符串轉(zhuǎn)換為整數(shù). 可選參數(shù)base代表從字符串轉(zhuǎn)換時(shí)的基礎(chǔ)/根據(jù)
intern(string)
Checks to see whether string is contained in an internal table of strings. If found, a copy of the internal string is returned. If not, string is added to the internal table and returned. This function is primarily used to get better performance in operations involving dictionary lookups. Interned strings are never garbage-collected. Not applicable to Unicode strings.
isinstance(object, classobj)
檢查object是否是classobj的事例或子類.也可用于檢查類型
issubclass(class1, class2)
檢查class1是否是class2的子類(派生類)
注意: issubclass(A , A )返回True
len(s)
返回序列s中包含的條目數(shù)目
list(s)
返回一個(gè)包含序列s中條目的新列表
locals()
返回一個(gè)與調(diào)用時(shí)局部名稱空間相對(duì)應(yīng)的字典
long(x [, base])
將一個(gè)數(shù)字或字符串轉(zhuǎn)換為長(zhǎng)整數(shù),可選參數(shù)base代表從字符串轉(zhuǎn)換時(shí)的基礎(chǔ)/根據(jù)
map(function, list, ...)
將序列l(wèi)ist中的每個(gè)元素傳遞給function函數(shù)做參數(shù),函數(shù)的返回值組成列表并返回.如果提供給多個(gè)列表,則函數(shù)應(yīng)包含有多個(gè)參數(shù),每個(gè)參數(shù)從不同的列表獲得.如果函數(shù)為None,則默認(rèn)為 identity function(?身份函數(shù)).如果None映射到多個(gè)列表,則返回一個(gè)包含元組的列表,元組的每個(gè)元素分別來(lái)自各個(gè)列表.如果有必要,短的列表將使用None來(lái)擴(kuò)充到與最長(zhǎng)列表長(zhǎng)度相等. map可以使用list comprehensions 來(lái)代替.例如map(function , alist ),可以使用[function (x) for x in alist ]來(lái)代替
參閱 zip (105).
max(s [, args, ...])
單個(gè)參數(shù)時(shí),返回序列s中的最大值.多個(gè)參數(shù)時(shí),返回值最大的參數(shù)
min(s [, args, ...])
單個(gè)參數(shù)時(shí),返回序列s中的最小值.多個(gè)參數(shù)時(shí),返回值最小的參數(shù)
oct(x)
將一個(gè)整數(shù)或者長(zhǎng)整數(shù)轉(zhuǎn)換為八進(jìn)制字符串
open(filename [, mode [, bufsize]])
打開(kāi)文件filename并返回一個(gè)文件對(duì)象(第十章,運(yùn)行環(huán)境). mode代表文件打開(kāi)的模式. 'r' 表示讀, 'w' 表示寫(xiě), 'a' 表示在文件末尾添加內(nèi)容. 還有一種更新模式,你只要在讀寫(xiě)模式后增加一個(gè)'+'就可以使用這種模式,如'r+' 或 'w+'.當(dāng)一個(gè)文件以更新模式打開(kāi),你就可以對(duì)這個(gè)文件進(jìn)行讀寫(xiě)操作.只要在任何讀取操作之前刷新所有的輸出緩沖就不會(huì)有問(wèn)題.如果一個(gè)文件以 'w+' 模式打開(kāi),它的長(zhǎng)度就度截為 0.當(dāng)mode省略時(shí),將會(huì)使用'w'模式.bufsize參數(shù)指定了緩沖行為, 0代表無(wú)緩沖,1代表行緩沖,其他正數(shù)代表一個(gè)大約的字節(jié)緩沖器大小,負(fù)數(shù)代表使用系統(tǒng)默認(rèn)緩沖器大小(也是默認(rèn)行為)
ord(c)
返回單個(gè)字符c的整數(shù)順序值.普通字符返回[0,255]中的一個(gè)值,Unicode字符返回 [0,65535]中的一個(gè)值
pow(x, y [, z])
返回x ** y ,如果z存在返回(x ** y ) % z
range([start,] stop [, step])
返回一個(gè)從start到stop的整數(shù)序列, step代表步進(jìn),默認(rèn)值為1. start默認(rèn)值為0.負(fù)數(shù)的step可以創(chuàng)建一個(gè)遞減的整數(shù)序列
參閱xrange (105)
raw_input([prompt])
從標(biāo)準(zhǔn)輸入(sys.stdin)中讀取一行,并把它作為字符串返回.如果提供了prompt,它將首先打印到標(biāo)準(zhǔn)輸出(sys.stdout).當(dāng)讀取到一個(gè)EOF時(shí),就會(huì)引發(fā)一個(gè)EOFError異常.如果readline模塊被導(dǎo)入,那么這個(gè)函數(shù)會(huì)使用它來(lái)提供更高級(jí)的功能
reduce(func, seq [, initializer])
函數(shù)從一個(gè)序列收集信息,然后只返回一個(gè)值(例如求和,最大值,等).它首先以序列的前兩個(gè)元素調(diào)用函數(shù),再將返回值和第三個(gè)參數(shù)作為參數(shù)調(diào)用函數(shù),依次執(zhí)行下去,返回最終的值. func函數(shù)有且只有兩個(gè)參數(shù).在seq為空時(shí),將使用初始值initializer.
reload(module)
重新導(dǎo)入一個(gè)已經(jīng)導(dǎo)入的模塊. module必須是一個(gè)已經(jīng)存在的模塊對(duì)象.一般情況下并不鼓勵(lì)使用這個(gè)函數(shù),除了在調(diào)試的時(shí)候.
當(dāng)一個(gè)模塊重導(dǎo)入時(shí),定義它的全局名稱空間的字典依然存在.Thus, definitions in the old module that aren’t part of the newly reloaded module are retained.模塊可以利用這個(gè)來(lái)檢查他們是否已經(jīng)被導(dǎo)入.
重導(dǎo)入一個(gè)使用C編寫(xiě)的模塊通常是不合法的
If any other modules have imported this module by using the from statement, they’ll continue to use the definitions in the previously imported module. This problem can be avoided by either reissuing the from statement after a module has been reloaded or using fully qualified names such as module.name .
如果有使用以前模塊中類創(chuàng)建的實(shí)例,它們將繼續(xù)使用以前的模塊
repr(object)
返回一個(gè)對(duì)象的標(biāo)準(zhǔn)字符串表示.與向后的引號(hào) `object` 相同.大多數(shù)情況下,返回的字符串可以使用eval()來(lái)再次創(chuàng)建這個(gè)對(duì)象.
round(x [, n])
Returns the result of rounding the floating-point number x to the closest multiple of 10 to the power minus n . If n is omitted, it defaults to 0. If two multiples are equally close, rounding is done away from 0 (例如, 0.5 is rounded to 1.0 and -0.5 is rounded to -1.0).
setattr(object, name, value)
設(shè)置一個(gè)對(duì)象的屬性. name是一個(gè)字符串. 相當(dāng)于object.name = value .
slice([start,] stop [, step])
返回一個(gè)代表指定數(shù)列中一個(gè)整數(shù)的切片對(duì)象.切片對(duì)象也可以有擴(kuò)展切片操作語(yǔ)句來(lái)產(chǎn)生.(第三章,序列和映射方法)
str(object)
返回表示對(duì)象的可打印形式的字符串.與print語(yǔ)句產(chǎn)生的字符串相同.
tuple(s)
從序列s中創(chuàng)建一個(gè)元組.如果s已經(jīng)是一個(gè)元組,則返回s
type(object)
返回object的類型,它是一個(gè)types模塊中定義type類型
參閱isinstance (102)
unichr(i)
將一個(gè)0到65535的整數(shù)轉(zhuǎn)換為一個(gè)Unicode字符
unicode(string [, encoding [, errors]])
將string轉(zhuǎn)換為Unicode字符串. encoding指定了string的數(shù)據(jù)編碼,它被省略時(shí),將使用sys.getdefaultencoding(). errors指定編碼錯(cuò)誤處理方式.('strict', 'ignore', 或 'replace' .參閱第三章和第九章中有關(guān)Unicode內(nèi)容)
vars([object])
返回object的 symbol table (通常在object的__dict__屬性).如果沒(méi)有給它提供參數(shù),則返回對(duì)應(yīng)當(dāng)前局部名稱空間的字典.
xrange([start,] stop [, step])
和range函數(shù)相似,但返回的是一個(gè)XRangeType對(duì)象.它生成一個(gè)迭代器,就是只有用那個(gè)數(shù)時(shí)才臨時(shí)通過(guò)計(jì)算提供值,而不是全部?jī)?chǔ)存它們.這樣在處理大的數(shù)列時(shí)能節(jié)省大量的內(nèi)存.
zip(s1 [, s2 [,..]])
用來(lái)將幾個(gè)序列組合成一個(gè)包含元組的序列,序列中的每個(gè)元素t[i ] = (s1[i ], s2[i ], ..., sn[i ]).結(jié)果與最短序列的長(zhǎng)度相等.
目錄
許多編程語(yǔ)言都有一個(gè)特殊的函數(shù),當(dāng)操作系統(tǒng)開(kāi)始運(yùn)行程序時(shí)會(huì)自動(dòng)執(zhí)行該函數(shù)。這個(gè)函數(shù)通常被命名為main(),并且依據(jù)語(yǔ)言標(biāo)準(zhǔn)具有特定的返回類型和參數(shù)。另一方面,Python解釋器從文件頂部開(kāi)始執(zhí)行腳本,并且沒(méi)有自動(dòng)執(zhí)行的特殊函數(shù)。
盡管如此,為程序的執(zhí)行定義一個(gè)起始點(diǎn)有助于理解程序是如何運(yùn)行的。Python程序員提出了幾種方式對(duì)此進(jìn)行實(shí)現(xiàn)。
本文結(jié)束時(shí),您將了解以下內(nèi)容:
Python中的基本main()函數(shù)
一些Python腳本中,包含一個(gè)函數(shù)定義和一個(gè)條件語(yǔ)句,如下所示:
此代碼中,包含一個(gè)main()函數(shù),在程序執(zhí)行時(shí)打印Hello World!。此外,還包含一個(gè)條件(或if)語(yǔ)句,用于檢查_(kāi)_name__的值并將其與字符串"__main__"進(jìn)行比較。當(dāng)if語(yǔ)句為T(mén)rue時(shí),Python解釋器將執(zhí)行main()函數(shù)。更多關(guān)于Python條件語(yǔ)句的信息可以由此獲得。
這種代碼模式在Python文件中非常常見(jiàn),它將作為腳本執(zhí)行并導(dǎo)入另一個(gè)模塊。為了幫助理解這段代碼的執(zhí)行方式,首先需要了解Python解釋器如何根據(jù)代碼的執(zhí)行方式設(shè)置__name__。
Python中的執(zhí)行模式
Python解釋器執(zhí)行代碼有兩種方式:
更多內(nèi)容可參考如何運(yùn)行Python腳本。無(wú)論采用哪種方式,Python都會(huì)定義一個(gè)名為_(kāi)_name__的特殊變量,該變量包含一個(gè)字符串,其值取決于代碼的使用方式。
本文將如下示例文件保存為execution_methods.py,以 探索 代碼如何根據(jù)上下文改變行為:
在此文件中,定義了三個(gè)對(duì)print()函數(shù)的調(diào)用。前兩個(gè)打印一些介紹性短語(yǔ)。第三個(gè)print()會(huì)先打印短語(yǔ)The value __name__ is,之后將使用Python內(nèi)置的repr()函數(shù)打印出__name__變量。
在Python中,repr()函數(shù)將對(duì)象轉(zhuǎn)化為供解釋器讀取的形式。上述示例通過(guò)使用repr()函數(shù)來(lái)強(qiáng)調(diào)__name__的值為字符串。更多關(guān)于repr()的內(nèi)容可參考Python文檔。
在本文中,您將隨處可見(jiàn)文件(file),模塊(module)和腳本(script)這三個(gè)字眼。實(shí)際上,三者之間并無(wú)太大的差別。不過(guò),在強(qiáng)調(diào)代碼目的時(shí),還是存在細(xì)微的差異:
“如何運(yùn)行Python腳本”一文也討論了三者的差別。
基于命令行執(zhí)行
在這類方法中,Python腳本將通過(guò)命令行來(lái)執(zhí)行。
執(zhí)行腳本時(shí),無(wú)法與Python解釋器正在執(zhí)行的代碼交互。關(guān)于如何通過(guò)命令行執(zhí)行代碼的詳細(xì)信息對(duì)本文而言并不重要,但您可以通過(guò)展開(kāi)下框閱讀更多有關(guān)Windows,Linux和macOS之間命令行差異的內(nèi)容。
命令行環(huán)境
不同的操作系統(tǒng)在使用命令行執(zhí)行代碼時(shí)存在細(xì)微的差異。
在Linux和macOS中,通常使用如下命令:
美元符號(hào)($)之前的內(nèi)容可能有所不同,具體取決于您的用戶名和計(jì)算機(jī)名稱。您鍵入的命令位于$之后。在Linux或macOS上,Python3的可執(zhí)行文件名為python3,因此可以通過(guò)輸入python3 script_name.py來(lái)運(yùn)行python腳本。
在Windows上,命令提示符通常如下所示:
根據(jù)您的用戶名,之前的內(nèi)容可能會(huì)有所不同,您輸入的命令位于之后。在Windows上,Python3的可執(zhí)行文件通常為python。因此可以通過(guò)輸入python script_name.py來(lái)運(yùn)行python腳本。
無(wú)論哪種操作系統(tǒng),本文的Python腳本的輸出結(jié)果都是相同的。因此本文以Linux和macOS為例。
使用命令行執(zhí)行execution_methods.py,如下所示:
在這個(gè)示例中,__name__具有值'__main__',其中引號(hào)(')表明該值為字符串類型。
請(qǐng)記住,在Python中,使用單引號(hào)(')和雙引號(hào)(")定義的字符串沒(méi)有區(qū)別。更多關(guān)于字符串的內(nèi)容請(qǐng)參考Python的基本數(shù)據(jù)類型。
如果在腳本中包含"shebang行"并直接執(zhí)行它(./execution_methods.py),或者使用IPython或Jupyter Notebook的%run,將會(huì)獲取相同的結(jié)果。
您還可以通過(guò)向命令行添加-m參數(shù)的方法實(shí)現(xiàn)以模塊的方式執(zhí)行。通常情況下,推薦如下方式pip: python3 -m pip install package_name。
添加-m參數(shù)將會(huì)運(yùn)行包中__main__.py的代碼。更多關(guān)于__main__.py文件的內(nèi)容可參考如何將開(kāi)源Python包發(fā)布到PyPI中。
在三種情況中,__name__都具有相同的值:字符串'__main__'。
技術(shù)細(xì)節(jié):Python文檔中具體定義了__name__何時(shí)取值為'__main__'。
當(dāng)通過(guò)標(biāo)準(zhǔn)輸入,腳本或者交互提示中讀取數(shù)據(jù)時(shí),模塊的__name__將取值為'__main__'。(來(lái)源)
__name__與__doc__,__package__和其他屬性一起存儲(chǔ)在模塊的全局命名空間。更多關(guān)于屬性的信息可參考Python數(shù)據(jù)模型文檔,特別是關(guān)于模塊和包的信息,請(qǐng)參閱Python Import文檔。
導(dǎo)入模塊或解釋器
接下來(lái)是Python解釋器執(zhí)行代碼的第二種方式:導(dǎo)入。在開(kāi)發(fā)模塊或腳本時(shí),可以使用import關(guān)鍵字導(dǎo)入他人已經(jīng)構(gòu)建的模塊。
在導(dǎo)入過(guò)程中,Python執(zhí)行指定模塊中定義的語(yǔ)句(但僅在第一次導(dǎo)入模塊時(shí))。要演示導(dǎo)入execution_methods.py文件的結(jié)果,需要啟動(dòng)Python解釋器,然后導(dǎo)入execution_methods.py文件:
在此代碼輸出中,Python解釋器執(zhí)行了三次print()函數(shù)調(diào)用。前兩行由于沒(méi)有變量,在輸出方面與在命令行上作為腳本執(zhí)行時(shí)完全相同。但是第三個(gè)輸出存在差異。
當(dāng)Python解釋器導(dǎo)入代碼時(shí),__name__的值與要導(dǎo)入的模塊的名稱相同。您可以通過(guò)第三行的輸出了解這一點(diǎn)。__name__的值為'execution_methods',是Python導(dǎo)入的.py文件。
注意如果您在沒(méi)有退出Python時(shí)再次導(dǎo)入模塊,將不會(huì)有輸出。
注意:更多關(guān)于導(dǎo)入在Python中如何工作的內(nèi)容請(qǐng)參考官方文檔和Python中的絕對(duì)和相對(duì)導(dǎo)入。
Main函數(shù)的最佳實(shí)踐
既然您已經(jīng)了解兩種執(zhí)行方式上的差異,那么掌握一些最佳實(shí)踐方案還是很有用的。它們將適用于編寫(xiě)作為腳本運(yùn)行的代碼或者在另一個(gè)模塊導(dǎo)入的代碼。
如下是四種實(shí)踐方式:
將大部分代碼放入函數(shù)或類中
請(qǐng)記住,Python解釋器在導(dǎo)入模塊時(shí)會(huì)執(zhí)行模塊中的所有代碼。有時(shí)如果想要實(shí)現(xiàn)用戶可控的代碼,會(huì)導(dǎo)致一些副作用,例如:
在這種情況下,想要實(shí)現(xiàn)用戶控制觸發(fā)此代碼的執(zhí)行,而不是讓Python解釋器在導(dǎo)入模塊時(shí)執(zhí)行代碼。
因此,最佳方法是將大部分代碼包含在函數(shù)或類中。這是因?yàn)楫?dāng)Python解釋器遇到def或class關(guān)鍵字時(shí),它只存儲(chǔ)這些定義供以后使用,并且在用戶通知之前不會(huì)實(shí)際執(zhí)行。
將如下代碼保存在best_practices.py以證明這個(gè)想法:
在此代碼中,首先從time模塊中導(dǎo)入sleep()。
在這個(gè)示例中,參數(shù)以秒的形式傳入sleep()函數(shù)中,解釋器將暫停一段時(shí)間再運(yùn)行。隨后,使用print()函數(shù)打印關(guān)于代碼描述的語(yǔ)句。
之后,定義一個(gè)process_data()函數(shù),執(zhí)行如下五項(xiàng)操作:
在命令行中執(zhí)行
當(dāng)你將此文件作為腳本用命令行執(zhí)行時(shí)會(huì)發(fā)生什么呢?
Python解釋器將執(zhí)行函數(shù)定義之外的from time import sleep和print(),之后將創(chuàng)建函數(shù)process_data()。然后,腳本將退出而不做任何進(jìn)一步的操作,因?yàn)槟_本沒(méi)有任何執(zhí)行process_data()的代碼。
如下是這段腳本的執(zhí)行結(jié)果:
我們?cè)谶@里看到的輸出是第一個(gè)print()的結(jié)果。注意,從time導(dǎo)入和定義process_data()函數(shù)不產(chǎn)生結(jié)果。具體來(lái)說(shuō),調(diào)用定義在process_data()內(nèi)部的print()不會(huì)打印結(jié)果。
導(dǎo)入模塊或解釋器執(zhí)行
在會(huì)話(或其他模塊)中導(dǎo)入此文件時(shí),Python解釋器將執(zhí)行相同的步驟。
Python解釋器導(dǎo)入文件后,您可以使用已導(dǎo)入模塊中定義的任何變量,類或函數(shù)。為了證明這一點(diǎn),我們將使用可交互的Python解釋器。啟動(dòng)解釋器,然后鍵入import best_practices:
導(dǎo)入best_practices.py后唯一的輸出來(lái)自process_data()函數(shù)外定義的print()。導(dǎo)入模塊或解釋器執(zhí)行與基于命令行執(zhí)行類似。
使用__name__控制代碼的執(zhí)行
如何實(shí)現(xiàn)基于命令行而不使用Python解釋器導(dǎo)入文件來(lái)執(zhí)行呢?
您可以使用__name__來(lái)決定執(zhí)行上下文,并且當(dāng)__name__等于"__main__"時(shí)才執(zhí)行process_data()。在best_practices.py文件中添加如下代碼:
這段代碼添加了一個(gè)條件語(yǔ)句來(lái)檢驗(yàn)__name__的值。當(dāng)值為"__main__"時(shí),條件為T(mén)rue。記住當(dāng)__name__變量的特殊值為"__main__"時(shí)意味著Python解釋器會(huì)執(zhí)行腳本而不是將其導(dǎo)入。
條件語(yǔ)塊內(nèi)添加了四行代碼(第12,13,14和15行):
現(xiàn)在,在命令行中運(yùn)行best_practices.py,并觀察輸出的變化:
首先,輸出顯示了process_data()函數(shù)外的print()的調(diào)用結(jié)果。
之后,data的值被打印。因?yàn)楫?dāng)Python解釋器將文件作為腳本執(zhí)行時(shí),變量__name__具有值"__main__",因此條件語(yǔ)句被計(jì)算為T(mén)rue。
接下來(lái),腳本將調(diào)用process_data()并傳入data進(jìn)行修改。當(dāng)process_data執(zhí)行時(shí),將輸出一些狀態(tài)信息。最終,將輸出modified_data的值。
現(xiàn)在您可以驗(yàn)證從解釋器(或其他模塊)導(dǎo)入best_practices.py后發(fā)生的事情了。如下示例演示了這種情況:
注意,當(dāng)前結(jié)果與將條件語(yǔ)句添加到文件末尾之前相同。因?yàn)榇藭r(shí)__name__變量的值為"best_practices",因此條件語(yǔ)句結(jié)果為False,Python將不執(zhí)行process_data()。
創(chuàng)建名為main()的函數(shù)來(lái)包含要運(yùn)行的代碼
現(xiàn)在,您可以編寫(xiě)作為腳本由從命令行執(zhí)行并導(dǎo)入且沒(méi)有副作用的Python代碼。接下來(lái),您將學(xué)習(xí)如何編寫(xiě)代碼并使其他程序員能輕松地理解其含義。
許多語(yǔ)言,如C,C++,Java以及其他的一些語(yǔ)言,都會(huì)定義一個(gè)叫做main()的函數(shù),當(dāng)編譯程序時(shí),操作系統(tǒng)會(huì)自動(dòng)調(diào)用該函數(shù)。此函數(shù)通常被稱為入口點(diǎn)(entry point),因?yàn)樗浅绦蜻M(jìn)入執(zhí)行的起始位置。
相比之下,Python沒(méi)有一個(gè)特殊的函數(shù)作為腳本的入口點(diǎn)。實(shí)際上在Python中可以將入口點(diǎn)定義成任何名稱。
盡管Python不要求將函數(shù)命名為main(),但是最佳的做法是將入口點(diǎn)函數(shù)命名為main()。這樣方便其他程序員定位程序的起點(diǎn)。
此外,main()函數(shù)應(yīng)該包含Python解釋器執(zhí)行文件時(shí)要運(yùn)行的任何代碼。這比將代碼放入條件語(yǔ)塊中更好,因?yàn)橛脩艨梢栽趯?dǎo)入模塊時(shí)重復(fù)使用main()函數(shù)。
修改best_practices.py文件如下所示:
在這個(gè)示例中,定義了一個(gè)main()函數(shù),它包含了上面的條件語(yǔ)句塊。之后修改條件語(yǔ)塊執(zhí)行main()。如果您將此代碼作為腳本運(yùn)行或?qū)?,將獲得與上一節(jié)相同的輸出。
在main()中調(diào)用其他函數(shù)
另一種常見(jiàn)的實(shí)現(xiàn)方式是在main()中調(diào)用其他函數(shù),而不是直接將代碼寫(xiě)入main()。這樣做的好處在于可以實(shí)現(xiàn)將幾個(gè)獨(dú)立運(yùn)行的子任務(wù)整合。
例如,某個(gè)腳本有如下功能:
如果在單獨(dú)的函數(shù)中各自實(shí)現(xiàn)這些子任務(wù),您(或其他用戶)可以很容易地實(shí)現(xiàn)代碼重用。之后您可以在main()函數(shù)中創(chuàng)建默認(rèn)的工作流。
您可以根據(jù)自己的情況選擇是否使用此方案。將任務(wù)拆分為多個(gè)函數(shù)會(huì)使重用更容易,但會(huì)增加他人理解代碼的難度。
修改best_practices.py文件如下所示:
在此示例代碼中,文件的前10行具有與之前相同的內(nèi)容。第12行的第二個(gè)函數(shù)創(chuàng)建并返回一些示例數(shù)據(jù),第17行的第三個(gè)函數(shù)模擬將修改后的數(shù)據(jù)寫(xiě)入數(shù)據(jù)庫(kù)。
第21行定義了main()函數(shù)。在此示例中,對(duì)main()做出修改,它將調(diào)用數(shù)據(jù)讀取,數(shù)據(jù)處理以及數(shù)據(jù)寫(xiě)入等功能。
首先,從read_data_from_web()中創(chuàng)建data。將data作為參數(shù)傳入process_data(),之后將返回modified_data。最后,將modified_data傳入write_data_to_database()。
腳本的最后兩行是條件語(yǔ)塊用于驗(yàn)證__name__,并且如果if語(yǔ)句為T(mén)rue,則執(zhí)行main()。
在命令行中運(yùn)行如下所示:
根據(jù)執(zhí)行結(jié)果,Python解釋器在執(zhí)行main()函數(shù)時(shí),將依次執(zhí)行read_data_from_web(),process_data()以及write_data_to_database()。當(dāng)然,您也可以導(dǎo)入best_practices.py文件并重用process_data()作為不同的數(shù)據(jù)輸入源,如下所示:
在此示例中,導(dǎo)入了best_practices并且將其簡(jiǎn)寫(xiě)為bp。
導(dǎo)入過(guò)程會(huì)導(dǎo)致Python解釋器執(zhí)行best_practices.py的全部代碼,因此輸出顯示解釋文件用途的信息。
然后,從文件中存儲(chǔ)數(shù)據(jù)而不是從Web中讀取數(shù)據(jù)。之后,可以重用best_practices.py文件中的process_data()和write_data_to_database()函數(shù)。在此情況下,可以利用代碼重寫(xiě)來(lái)取代在main()函數(shù)中實(shí)現(xiàn)全部的代碼邏輯。
實(shí)踐總結(jié)
以下是Python中main()函數(shù)的四個(gè)關(guān)鍵最佳實(shí)踐:
結(jié)論
恭喜!您現(xiàn)在已經(jīng)了解如何創(chuàng)建Python main()函數(shù)了。
本文介紹了如下內(nèi)容:
現(xiàn)在,您可以開(kāi)始編寫(xiě)一些非常棒的關(guān)于Python main()函數(shù)代碼啦!
打開(kāi)IDLE python GUI,點(diǎn)擊開(kāi)始-所有程序-python2.7-IDLE python GUI,或者直接進(jìn)入dos環(huán)境,或者其他的IDLE。
請(qǐng)點(diǎn)擊輸入圖片描述
首先,創(chuàng)建一個(gè)簡(jiǎn)單的自定義函數(shù),定義為K函數(shù)。
請(qǐng)點(diǎn)擊輸入圖片描述
假如x==Kill,那么,就可以代入剛才所創(chuàng)建的K函數(shù),最后返回一個(gè)語(yǔ)句,x為任意字符,空白字符也可以。
請(qǐng)點(diǎn)擊輸入圖片描述
要注意的是,用def創(chuàng)建函數(shù)的時(shí)候,k(x)括號(hào)里面是不用雙引號(hào)的,而調(diào)用自定義函數(shù)的時(shí)候,在括號(hào)了就要加上雙引號(hào)。
上面的定義函數(shù)比較簡(jiǎn)單,只用了一個(gè)print輸出語(yǔ)句,現(xiàn)在,定義一個(gè)累加的函數(shù),就要用到while函數(shù)和if函數(shù)了。
請(qǐng)點(diǎn)擊輸入圖片描述
A函數(shù)是用來(lái)計(jì)算累加的,其中用到了一個(gè)while循環(huán)和if判斷,x為自定義變量,假如現(xiàn)在X為100,也就是說(shuō)此函數(shù)計(jì)算1+2+3+...+100的和。
請(qǐng)點(diǎn)擊輸入圖片描述
要在 Python 3 中創(chuàng)建函數(shù),可以使用以下代碼:isPalindrome()
此代碼定義一個(gè)名為的函數(shù),該函數(shù)將字符串作為其輸入。該函數(shù)將字符串轉(zhuǎn)換為小寫(xiě),然后循環(huán)遍歷字符,僅將字母數(shù)字字符添加到列表中。最后,該函數(shù)檢查字符列表是否等于其反向,如果是這種情況,則返回,否則返回。isPalindrome()TrueFalse
您可以通過(guò)使用字符串作為參數(shù)調(diào)用此函數(shù)來(lái)使用它。例如:
對(duì)函數(shù)的這些調(diào)用將返回第一個(gè)字符串(因?yàn)樗腔匚模┖偷诙€(gè)字符串(因?yàn)樗彩且粋€(gè)回文)。isPalindrome()TrueTrue
請(qǐng)注意,此代碼只是一個(gè)示例,可能不適用于所有情況。您可能需要調(diào)整代碼以滿足您的特定要求。
回答不易望請(qǐng)采納
當(dāng)前題目:關(guān)于python3x創(chuàng)建函數(shù)的信息
標(biāo)題URL:http://jinyejixie.com/article10/hpdigo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信公眾號(hào)、網(wǎng)站導(dǎo)航、全網(wǎng)營(yíng)銷推廣、面包屑導(dǎo)航、靜態(tài)網(wǎng)站、動(dòng)態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)