IT 森林

听说你会 Python ?

2018-07-27  本文已影响25人  _小迷糊_997

前言

最近觉得 Python 太“简单了”,于是在朋友面前放肆了一把:“我觉得 Python 是世界上最简单的语言!”。朋友嘴角闪过了一丝轻蔑的微笑(内心 OS:Naive!,作为一个 Python 开发者,我必须要给你一点人生经验,不然你不知道天高地厚!)于是朋友给我了一份满分 100 分的题,然后这篇文章就是记录下做这套题所踩过的坑。

1.列表生成器

描述

下面的代码会报错,为什么?

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.装饰器

描述

我想写一个类装饰器用来度量函数/方法运行时间

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资料】即可获取

入门进阶书籍
上一篇 下一篇

猜你喜欢

热点阅读