专栏名称: Python开发者
人生苦短,我用 Python。伯乐在线旗下账号「Python开发者」分享 Python 相关的技术文章、工具资源、精选课程、热点资讯等。
目录
相关文章推荐
Python开发者  ·  外网热议:为什么 DeepSeek ... ·  6 小时前  
51好读  ›  专栏  ›  Python开发者

编写高效且优雅的 Python 代码

Python开发者  · 公众号  · Python  · 2017-04-20 20:10

正文

请到「今天看啥」查看全文


# 2

# 1

# 0

# 但无法作用于 集合 和 迭代器

reversed ( iter_example ) # TypeError: argument to reversed() must be a sequence


除此以外,还可以通过实现类里的__reversed__方法,将类进行反向迭代:


class Countdown :

def __init__ ( self , start ) :

self . start = start

# 正向迭代

def __iter__ ( self ) :

n = self . start

while n > 0 :

yield n

n -= 1

# 反向迭代

def __reversed__ ( self ) :

n = 1

while n self . start :

yield n

n += 1

for i in reversed ( Countdown ( 4 )) :

print ( i )

# 1

# 2

# 3

# 4

for i in Countdown ( 4 ) :

print ( i )

# 4

# 3

# 2

# 1


try/except/else/finally


  • 如果try内没有发生异常,则调用else内的代码

  • else会在finally之前运行

  • 最终一定会执行finally,可以在其中进行清理工作


函数


使用装饰器


装饰器用于在不改变原函数代码的情况下修改已存在的函数。常见场景是增加一句调试,或者为已有的函数增加log监控


举个栗子:


def decorator_fun ( fun ) :

def new_fun ( * args , ** kwargs ) :

print ( 'current fun:' , fun . __name__ )

print ( 'position arguments:' , args )

print ( 'key arguments:' , ** kwargs )

result = fun ( * args , ** kwargs )

print ( result )

return result

return new _ fun

@ decorator_fun

def add ( a , b ) :

return a + b

add ( 3 , 2 )

# current fun: add

# position arguments: (3, 2)

# key arguments: {}

# 5


除此以外,还可以编写接收参数的装饰器,其实就是在原本的装饰器上的外层又嵌套了一个函数:


def read_file ( filename = 'results.txt' ) :

def decorator_fun ( fun ) :

def new_fun ( * args , ** kwargs ) :

result = fun ( * args , ** kwargs )

with open ( filename , 'a' ) as f :

f . write ( result + '\n' )

return result

return new_fun

return decorator_fun

# 使用装饰器时代入参数

@ read_file ( filename = 'log.txt' )

def add ( a , b ) :

return a + b


但是像上面那样使用装饰器的话有一个问题:


@ decorator_fun

def add ( a , b ) :

return a + b

print ( add . __name__ )

# new_fun


也就是说原函数已经被装饰器里的new_fun函数替代掉了。调用经过装饰的函数,相当于调用一个新函数。查看原函数的参数、注释、甚至函数名的时候,只能看到装饰器的相关信息。为了解决这个问题,我们可以使用 Python 自带的functools.wraps方法。


stackoverflow: What does functools.wraps do?


functools.wraps是个很 hack 的方法,它本事作为一个装饰器,做用在装饰器内部将要返回的函数上。也就是说,它是装饰器的装饰器,并且以原函数为参数,作用是保留原函数的各种信息,使得我们之后查看被装饰了的原函数的信息时,可以保持跟原函数一模一样。


from functools import wraps

def decorator_fun ( fun ) :

@ wraps ( fun )

def new_fun ( * args , ** kwargs ) :

result = fun ( * args , ** kwargs )

print ( result )

return result

return new _ fun

@ decorator_fun

def add ( a , b ) :

return a + b

print ( add . __name__ )

# add


此外,有时候我们的装饰器里可能会干不止一个事情,此时应该把事件作为额外的函数分离出去。但是又因为它可能仅仅和该装饰器有关,所以此时可以构造一个装饰器类。原理很简单,主要就是编写类里的__call__方法,使类能够像函数一样的调用。


from functools import wraps

class logResult ( object ) :

def __init__ ( self , filename = 'results.txt' ) :

self . filename = filename

def __call__ ( self , fun ) :

@ wraps ( fun )

def new_fun ( * args , ** kwargs ) :

result = fun ( * args , ** kwargs )

with open ( filename , 'a' ) as f :

f . write ( result + '\n' )

return result

self . send_notification ()







请到「今天看啥」查看全文