目录
一.Python函数的工作方式
1.函数是“一等公民”
在Python中,函数是“一等公民”,这意味着它们与任何其他对象(整数、字符串、列表、模块等)是同等的。您可以动态地创建或销毁它们,将它们作为参数传递给其他函数,将它们作为返回值返回,等等。
#1 作为参数传递给其他函数
>>> def gyf(func):
return func('gyf')
>>> def hello(n):
return f"Hello,{n}"
>>> hello(1)
'Hello,1'
'''函数作为参数,不带括号
'''
>>> gyf(hello)
'Hello,gyf'
#2.内部函数
可以在其他函数中定义函数。这种功能称为内部功能
>>> def gyf():
print('main ... somehing')
def hello():
print('Hello,gyf')
hello()
>>> gyf
<function gyf at 0x00000000032E6EA0>
>>> gyf()
main ... somehing
Hello,gyf
'''内部函数由于它们的本地作用域,不能在gyf()函数之外使用。
'''
>>> hello()
Traceback (most recent call last):
File "<pyshell#290>", line 1, in <module>
zzz()
NameError: name 'zzz' is not defined
#3 作为返回值返回
>>> def gyf():
print('main ... somehing')
def hello():
print('Hello,gyf')
return hello
>>> gyf
<function gyf at 0x00000000032FD0D0>
>>> gyf()
main ... somehing
<function gyf.<locals>.hello at 0x00000000032E6EA0>
'''gyf()函数中return hello,没加括号,返回的是对该函数的引用
'''
>>> gyf()()
main ... somehing
Hello,gyf
2.一些装饰器的有用示例
#1. 计时功能的装饰器
>>> import functools
>>> import time
>>>
>>> def timer(func):
'''返回被装饰函数的执行时间'''
@functools.wraps(func)
def wrapper_timer(*args,**kwargs):
start_time = time.perf_counter()
value = func(*args,**kwargs)
end_time = time.perf_counter()
t = end_time - start_time
print(f"Finished {func.__name__} in {t}")
return value
return wrapper_timer
>>> @timer
def waste_some_time(n):
for i in range(n):
sum([x for x in range(1000000)])
>>> waste_some_time
<function waste_some_time at 0x0000000003300400>
'''计时
'''
>>> waste_some_time(5)
Finished waste_some_time in 0.5429782879946288
装饰器并不会修改原始函数的参数签名以及返回值。 使用 *args
和 **kwargs
目的就是确保任何参数都能适用。 而返回结果值基本都是调用原始函数 func(*args, **kwargs)
的返回结果,其中func就是原始函数。
一个装饰器就是一个函数,它接受一个函数作为参数并返回一个新的函数,下面两种定义方法是一样的:
'''1
'''
>>> @timer
def waste_some_time(n):
pass
'''2
'''
>>> def waste_some_time(n):
pass
>>> waste_some_time = timer(waste_some_time)
#2 注册插件的装饰器
#定义插件字典
>>> PLUGINS = dict()
#装饰器
>>> def plugin_register(func):
PLUGINS[func.__name__] = func
return func
#一个插件的定义函数,被plugin_register装饰
>>> @plugin_register
def one_plugin(name):
print(f"Hello,{name}")
>>> one_plugin('gyf')
Hello,gyf
#插件函数执行后,插件加入到了PLUGINS字典中
>>> PLUGINS
{'one_plugin': <function one_plugin at 0x0000000002ED3048>}
这样无需维护插件记录,记录是在插件注册时创建的,这使得添加新插件变得很简单:只需定义函数并用修饰@register
。
Python 中的globals() 函数会以字典类型返回当前位置的全部全局变量,globals()的工作方式与之相似。