據說你會 Python ?

前言

最近以爲 Python 太「簡單了」,因而在朋友面前放肆了一把:「我以爲 Python 是世界上最簡單的語言!」。朋友嘴角閃過了一絲輕蔑的微笑(心裏 OS:Naive!,做爲一個 Python 開發者,我必需要給你一點人生經驗,否則你不知道天高地厚!)因而朋友給我了一份滿分 100 分的題,而後這篇文章就是記錄下作這套題所踩過的坑。app

1.列表生成器函數

描述code

下面的代碼會報錯,爲何?blog

1 class A(object):
2     x = 1
3     gen = (x for _ in xrange(10))  # gen=(x for _ in range(10))
4
5
6 if __name__ == "__main__":
7      print(list(A.gen))

答案作用域

這個問題是變量做用域問題,在 gen=(x for _ in xrange(10)) 中 gen 是一個 generator ,在 generator 中變量有本身的一套做用域,與其他做用域空間相互隔離。所以,將會出現這樣的 NameError: name 'x' is not defined 的問題,那麼解決方案是什麼呢?答案是:用 lambda 。開發

1 class A(object):
2    x = 1
3    gen = (lambda x: (x for _ in xrange(10)))(x)  # gen=(x for _ in range(10))
4
5
6 if __name__ == "__main__":
7   print(list(A.gen))

或者文檔

1 class A(object):
2    x = 1
3    gen = (A.x for _ in xrange(10))  # gen=(x for _ in range(10))
4
5
6 if __name__ == "__main__":
7    print(list(A.gen))

2.裝飾器get

描述generator

我想寫一個類裝飾器用來度量函數/方法運行時間it

1 import time
2
3 class Timeit(object):
4    def __init__(self, func):
5       self._wrapped = func
6
7    def __call__(self, *args, **kws):
8        start_time = time.time()
9        result = self._wrapped(*args, **kws)
10       print("elapsed time is %s " % (time.time() - start_time))
11       return result

這個裝飾器可以運行在普通函數上:

1 @Timeit
2 def func():
3    time.sleep(1)
4    return "invoking function func"
5
6
7 if __name__ == '__main__':
8    func()  # output: elapsed time is 1.00044410133

可是運行在方法上會報錯,爲何?

1 class A(object):
2   @Timeit
3    def func(self):
4        time.sleep(1)
5        return 'invoking method func'
6
7
8 if __name__ == '__main__':
9     a = A()
10    a.func()  # Boom!

若是我堅持使用類裝飾器,應該如何修改?

答案

使用類裝飾器後,在調用 func 函數的過程當中其對應的 instance 並不會傳遞給 call 方法,形成其 mehtod unbound ,那麼解決方法是什麼呢?描述符賽高

1 class Timeit(object):
2    def __init__(self, func):
3        self.func = func
4
5    def __call__(self, *args, **kwargs):
6        print('invoking Timer')
7
8    def __get__(self, instance, owner):
9        return lambda *args, **kwargs: self.func(instance, *args, **kwargs)

結語

感謝朋友一套題讓我開啓新世界的大門。說實話 Python 的動態特性可讓其用衆多 black magic 去實現一些很舒服的功能,固然這也對咱們對語言特性及坑的掌握也變得更嚴格了,願各位 Pythoner 沒事閱讀官方文檔,早日達到裝逼如風,常伴吾身的境界。

小編也準備許多的Python書籍資料是文件因平臺沒法放想要獲取加羣QQ:686183764 備註【Python資料】便可獲取

入門進階書籍

相關文章
相關標籤/搜索