首發於微信公衆號:Python編程時光
'
每週三更新五個冷知識,歡迎前往訂閱!html
對於 _
,我想不少人都很是熟悉。python
給變量取名好艱難,用 _
; 懶得長長的變量名,用 _
; 無用的垃圾變量,用 _
;git
以上,咱們都很熟悉了,今天要介紹的是他在交互式中使用。github
>>> 3 + 4
7
>>> _
7
>>> name='ming'
>>> name
'ming'
>>> _
'ming'
複製代碼
它能夠返回上一次的運行結果。編程
可是,若是是print函數打印出來的就不行了。bash
>>> 3 + 4
7
>>> _
7
>>> print("ming")
ming
>>> _
7
複製代碼
我本身寫了個例子,驗證了下,用__repr__
輸出的內容能夠被獲取到的。 首先,在咱們的目錄下,寫一個文件 ming.py。內容以下服務器
# ming.py
class mytest():
def __str__(self):
return "hello"
def __repr__(self):
return "world"
複製代碼
而後在這個目錄下進入交互式環境。微信
>>> import ming
>>> mt=ming.mytest()
>>> mt
world
>>> print(mt)
hello
>>> _
world
複製代碼
知道這兩個魔法方法的人,一看就明白了。網絡
反轉序列並不難,可是如何作到最優雅呢?app
先來看看,正常是如何反轉的。
最簡單的方法是使用列表自帶的reverse()方法。
>>> ml = [1,2,3,4,5]
>>> ml.reverse()
>>> ml
[5, 4, 3, 2, 1]
複製代碼
但若是你要處理的是字符串,reverse就無能爲力了。你能夠嘗試將其轉化成list,再reverse,而後再轉化成str。轉來轉去,也太麻煩了吧?須要這麼多行代碼(後面三行是不能合併成一行的),一點都Pythonic。
mstr1 = 'abc'
ml1 = list(mstr1)
ml1.reverse()
mstr2 = str(ml1)
複製代碼
對於字符串還有一種稍微複雜一點的,是自定義遞歸函數來實現。
def my_reverse(str):
if str == "":
return str
else:
return my_reverse(str[1:]) + str[0]
複製代碼
在這裏,介紹一種最優雅的反轉方式,使用切片,無論你是字符串,仍是列表,簡直通殺。
>>> mstr = 'abc'
>>> ml = [1,2,3]
>>> mstr[::-1]
'cba'
>>> ml[::-1]
[3, 2, 1]
複製代碼
上面才提到遞歸,你們都知道使用遞歸是有風險的,遞歸深度過深容易致使堆棧的溢出。若是你這字符串太長啦,使用遞歸方式反轉,就會出現問題。
那到底,默認遞歸次數限制是多少呢?
>>> import sys
>>> sys.getrecursionlimit()
1000
複製代碼
能夠查,固然也能夠自定義修改次數,退出即失效。
>>> sys.setrecursionlimit(2000)
>>> sys.getrecursionlimit()
2000
複製代碼
搭建FTP,或者是搭建網絡文件系統,這些方法都可以實現Linux的目錄共享。可是FTP和網絡文件系統的功能都過於強大,所以它們都有一些不夠方便的地方。好比你想快速共享Linux系統的某個目錄給整個項目團隊,還想在一分鐘內作到,怎麼辦?很簡單,使用Python中的SimpleHTTPServer。
SimpleHTTPServer是Python 2自帶的一個模塊,是Python的Web服務器。它在Python 3已經合併到http.server模塊中。具體例子以下,如不指定端口,則默認是8000端口。
# python2
python -m SimpleHTTPServer 8888
# python3
python3 -m http.server 8888
複製代碼
SimpleHTTPServer有一個特性,若是待共享的目錄下有index.html,那麼index.html文件會被視爲默認主頁;若是不存在index.html文件,那麼就會顯示整個目錄列表。
if else 用法能夠說最基礎的語法表達式之一,可是今天不是講這個的,必定要講點不同的。
if else 早已爛大街,但可能有不少人都未曾見過 for else 和 try else 的用法。爲何說它曾讓我暈頭轉向,由於它不像 if else 那麼直白,非黑即白,腦子常常要想一下才能才反應過來代碼怎麼走。反正我是這樣的。
先來講說,for else
def check_item(source_list, target):
for item in source_list:
if item == target:
print("Exists!")
break
else:
print("Does not exist")
複製代碼
在往下看以前,你能夠思考一下,什麼狀況下才會走 else。是循環被 break,仍是沒有break?
給幾個例子,你體會一下。
check_item(["apple", "huawei", "oppo"], "oppo")
# Exists!
check_item(["apple", "huawei", "oppo"], "vivo")
# Does not exist
複製代碼
能夠看出,沒有被 break 的程序纔會正常走else流程。
再來看看,try else 用法。
def test_try_else(attr1 = None):
try:
if attr1:
pass
else:
raise
except:
print("Exception occurred...")
else:
print("No Exception occurred...")
複製代碼
一樣來幾個例子。當不傳參數時,就拋出異常。
test_try_else()
# Exception occurred...
test_try_else("ming")
# No Exception occurred...
複製代碼
能夠看出,沒有 try 裏面的代碼塊沒有拋出異常的,會正常走else。
總結一下,for else 和 try else 相同,只要代碼正常走下去不被 break,不拋出異常,就能夠走else。
求一個字符串裏,某子字符(串)出現的次數。在Python中使用 count() 函數,就能夠輕鬆實現。
好比下面幾個常規例子
>>> "aabb".count("a")
2
>>> "aabb".count("b")
2
>>> "aabb".count("ab")
1
複製代碼
可是若是使用空字符串呢,你可能想不到會是這樣的結果。
>>> "aabb".count("")
5
複製代碼
具體緣由,我不敢妄下結論。
由此我還衍生出另外一個想法,實驗了下。不知道空字符串,是一種什麼樣的存在,難道字母與字母之間 「縫隙」 也算嗎?
>>> "" in ""
True
>>> "" in "ab"
True
複製代碼
有興趣的能夠去看看CPython的源碼實現。
從初中開始,咱們就開始接觸了負數
這個概念。知道了負負得正
,這和武俠世界裏的以毒功毒
,有點神似。
Python 做爲一門高級語言,它的編寫符合人類的思惟邏輯,這其中也包括負負得正
這個思想。
>>> 5-3
2
>>> 5--3
8
>>> 5+-3
2
>>> 5++3
8
>>> 5---3
2
複製代碼
在 Python2 中,數字能夠與字符串直接比較。結果是數值永遠比字符串小。
>>> 100000000 < ""
True
>>> 100000000 < "ming"
True
複製代碼
但在 Python3 中,卻不行。
>>> 100000000 < ""
TypeError: '<' not supported between instances of 'int' and 'str'
複製代碼
在Python 2中x的值在一個循環執行以後被改變了。
# Python2
>>> x = 1
>>> [x for x in range(5)]
[0, 1, 2, 3, 4]
>>> x
4
複製代碼
不過在Python3 中這個問題已經獲得解決了。
# Python3
>>> x = 1
>>> [x for x in range(5)]
[0, 1, 2, 3, 4]
>>> x
1
複製代碼
字典不可排序的思想,彷佛已經根深蒂固。
# Python2.7.10
>>> mydict = {str(i):i for i in range(5)}
>>> mydict
{'1': 1, '0': 0, '3': 3, '2': 2, '4': 4}
複製代碼
在 Python3 中字典已是有序的。
# Python3.6.7
>>> mydict = {str(i):i for i in range(5)}
>>> mydict
{'0': 0, '1': 1, '2': 2, '3': 3, '4': 4}
複製代碼
先給看一個示例
>>> False == False == True
False
複製代碼
你知道這個表達式會返回 False 嗎?
我再給你舉個例子,你可能就懂了。
f 18 < age < 60:
print("young man")
複製代碼
若是還不明白,再給你整個等價寫法。
>>> False == False and False == True
False
複製代碼
直接看下列例子。
在Python 2.x 中
>>> value = 11
>>> valuе = 32
File "<stdin>", line 1
valuе = 32
^
SyntaxError: invalid syntax
複製代碼
在Python 3.x 中
>>> value = 11
>>> valuе = 32
>>> value
11
複製代碼
我相信你一開始看到這裏,必定是目瞪口呆。你能夠在本身的電腦上嘗試一下,你會發現你無論在哪一個版本的 Python 裏運行都沒有問題。
若是你想重現我這個場景,你可能複製我上面的代碼粘貼至本身的命令行中便可。
在這裏,也不賣關子了,上面代碼中第二行的 е
和 第一行的 e
是不同的。
第二行的 e
是 Cyrillic(西里爾)字母,而不是咱們熟悉的英文字母。
>>> ord('е') # cyrillic 'e' (Ye)
1077
>>> ord('e') # latin 'e', as used in English and typed using standard keyboard
101
>>> 'е' == 'e'
False
複製代碼
細思恐極,平時可千萬不要得罪同事們,萬一辭職的時候,把你項目裏的 e
全局替換成 e
,到時候連錯都不知道錯哪了哈哈。
在大多數狀況下,這個等式是成立的。
>>> n1 = 10086
>>> n2 = +n1
>>>
>>> n1 == n2
True
複製代碼
什麼狀況下,這個等式會不成立呢?
因爲Counter的機制,+
用於兩個 Counter 實例相加,而相加的結果若是元素的個數 <=
0,就會被丟棄。
>>> from collections import Counter
>>> ct = Counter('abcdbcaa')
>>> ct
Counter({'a': 3, 'b': 2, 'c': 2, 'd': 1})
>>> ct['c'] = 0
>>> ct['d'] = -2
>>>
>>> ct
Counter({'a': 3, 'b': 2, 'c': 0, 'd': -2})
>>>
>>> +ct
Counter({'a': 3, 'b': 2})
複製代碼
import 是 Python 導包的方式。
你知道 Python 中內置了一些頗有(wu)趣(liao)的包嗎?
Hello World
>>> import __hello__
Hello World!
複製代碼
Python之禪
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
複製代碼
反地心引力漫畫
在 cmd 窗口中導入antigravity
>>> import antigravity
複製代碼
就會自動打開一個網頁。
在開始講以前,你能夠試着運行一下下面這小段代碼。
a = 1
def func01():
a += 1
func01()
複製代碼
看似沒有毛病,但實則已經犯了一個很基礎的問題,這個報錯至關常見吧?
>>> func01()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in func01
UnboundLocalError: local variable 'a' referenced before assignment
複製代碼
回顧一下,什麼是局部變量?在非全局下定義聲明的變量都是局部變量。
當程序運行到 a += 1
時,Python 解釋器就認爲在函數內部要給 a
這個變量賦值,固然就把 a
當作局部變量了,報錯是理所固然的。