python3 定制print

和C語言一樣亮垫,python的print功能通過內(nèi)建函數(shù)實現(xiàn),而不是通過statement實現(xiàn)伟骨。這意味著饮潦,名稱print可以被重新定義,和一般函數(shù)無異携狭。

例如继蜡,我們想設置print的默認參數(shù)為sep=', ',end='.\n'逛腿,可做如下操作:

pprint = print                                                      # 保存內(nèi)建print的指針

print = lambda *objects: pprint(*objects, sep=', ', end='.\n')      # 令print以所需參數(shù)調(diào)用pprint

print(1, 2)                                                         # 測試
>> 1, 2.

成功稀并。

為什么非要先把print保存在pprint里?為什么不能這樣寫:

print = lambda *object: print(*object, sep=', ', end='.\n') 

print(1, 2)

畢竟单默,類似 L = L + [3]的語句都沒問題碘举。


錯誤提示.png

這是怎么回事?

首先搁廓,這牽扯到函數(shù)中變量解引用的搜索順序引颈。即,local境蜕、nonlocal(若干層)蝙场、global、built-in汽摹。執(zhí)行print(1, 2)時李丰,lambda的local中沒有print,global中有print逼泣。但global空間中的print是我們自己定義的趴泌,只接受一個*object參數(shù)的print,不是built-in print拉庶。

但疑云未散嗜憔,按列表操作 L = L + [3] 的精神,名稱L替換為所引用的列表氏仗,和 [3] 拼接吉捶,結(jié)果命名為L。類似地皆尔,定義時呐舔,將lambda中的print替換為built-in print,生成的函數(shù)命名為print慷蠕,錯在何處珊拼?原因在于,函數(shù)體不在定義時執(zhí)行流炕。而解引用發(fā)生在語句執(zhí)行時澎现,也就是函數(shù)被調(diào)用的時候仅胞。調(diào)用時(不是定義時)print指什么,才決定函數(shù)執(zhí)行的效果剑辫。本例中干旧,函數(shù)執(zhí)行時名稱print已經(jīng)被自己的定義語句覆蓋,意外地產(chǎn)生了調(diào)用自身的結(jié)果妹蔽。

如此椎眯,python函數(shù)對象就像一個記錄著幾行代碼的清單,只有在調(diào)用時才會執(zhí)行所持有的代碼胳岂,代碼中解引用的操作是在調(diào)用時發(fā)生的盅视。閉包 函數(shù)工廠中介紹了一個更微妙的例子。

另外旦万,按照錯誤提示改變lambda的參數(shù)列表闹击,使之接收sep和end,也不能達到目的(會產(chǎn)生無限遞歸)成艘。原因還是赏半,此時global空間中的print遮蔽了built-in空間中的print,lambda中調(diào)用built-in中print的意圖無法實現(xiàn)淆两。

覆蓋了內(nèi)建print的print需要調(diào)用內(nèi)建print断箫,所以內(nèi)建print必須用某種方式保存下來。問題轉(zhuǎn)化為如何進行函數(shù)狀態(tài)保存秋冰,那么閉包仲义、默認參數(shù)、函數(shù)屬性剑勾、類埃撵,都是可以嘗試的方法。

函數(shù)閉包:

def makeopen():
    pprint = print
    return lambda *objects: pprint(*objects, sep=', ', end='.\n')

open = makeopen()

open(1, 2, 4)
>> 1, 2, 4.

其他方法請君自行探索虽另。


就這個具體問題而言暂刘,不使用內(nèi)建print函數(shù)或許是最好的方法:

import sys
def print(*args, sep=', ', end='.\n', file=sys.stdout):
    file.write(sep.join(str(arg) for arg in args) + end)
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市捂刺,隨后出現(xiàn)的幾起案子谣拣,更是在濱河造成了極大的恐慌,老刑警劉巖族展,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件森缠,死亡現(xiàn)場離奇詭異,居然都是意外死亡仪缸,警方通過查閱死者的電腦和手機贵涵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人独悴,你說我怎么就攤上這事÷辔荆” “怎么了刻炒?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長自沧。 經(jīng)常有香客問我坟奥,道長,這世上最難降的妖魔是什么拇厢? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任爱谁,我火速辦了婚禮,結(jié)果婚禮上孝偎,老公的妹妹穿的比我還像新娘访敌。我一直安慰自己,他們只是感情好衣盾,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布寺旺。 她就那樣靜靜地躺著,像睡著了一般势决。 火紅的嫁衣襯著肌膚如雪阻塑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天果复,我揣著相機與錄音陈莽,去河邊找鬼。 笑死虽抄,一個胖子當著我的面吹牛走搁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播迈窟,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼朱盐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了菠隆?” 一聲冷哼從身側(cè)響起兵琳,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎骇径,沒想到半個月后躯肌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡破衔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年清女,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晰筛。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡嫡丙,死狀恐怖拴袭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情曙博,我是刑警寧澤拥刻,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站父泳,受9級特大地震影響般哼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜惠窄,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一蒸眠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧杆融,春花似錦楞卡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至介劫,卻和暖如春徽惋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背座韵。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工险绘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人誉碴。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓宦棺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親黔帕。 傳聞我的和親對象是個殘疾皇子代咸,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348