Python 面试题:函数式编程
交换变量值
作用域
Python 的作用域可以分为四种:
- L(Local) 局部作用域
- E(Enclosing) 闭包函数外的函数中
- G(Global) 全局作用域
- B(Built-in) 内建作用域
变量/函数 的查找顺序:
- L –> E –> G –>B
如何查找模块中的全局变量和局部变量
- globals() :以 dict 的方式存储所有全局变量
- locals():以 dict 的方式存储所有局部变量
def foo():
print("I am a func")
def bar():
foo="I am a string"
foo_dup = globals().get("foo")
foo_dup()
bar()
# 输出
# I am a func
other = "test"
def foobar():
name = "MING"
gender = "male"
for key,value in locals().items():
print(key, "=", value)
foobar()
偏函数
- 如果需要减少某个函数的参数个数,你可以使用 functools.partial() 。 partial() 函数允许你给一个或多个参数设置固定的值,减少接下来被调用时的参数个数。
from functools import partial
s1 = partial(spam, 1) # a = 1
s1(2, 3, 4)
----
1 2 3 4
什么是闭包?
- 在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。其实装饰函数,很多都是闭包。
- 嵌套函数如果没有访问闭包作用域的本地变量,那就不能称为闭包。
- 对象是带有方法的数据,闭包是带有数据的函数。闭包是一个持久的局部变量作用域。
- 闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。
如何访问闭包中定义的变量?
- 通常来讲,闭包的内部变量对于外界来讲是完全隐藏的。 但是,你可以通过编写访问函数并将其作为函数属性绑定到闭包上来实现这个目的
def sample():
n = 0
# Closure function
def func():
print('n=', n)
# Accessor methods for n
def get_n():
return n
def set_n(value):
nonlocal n
n = value
# Attach as function attributes
func.get_n = get_n
func.set_n = set_n
return func
什么是装饰器
- 装饰器是一种函数,它能在不修改代码的情况下扩展其他函数的功能。装饰器的作用为已经存在的对象添加额外功能,能让之前的代码可以复用。
- 一种 python 的语法糖,与装饰器模式无关(面向对象的编程方法)。
装饰器的应用场景
-
异常捕捉:会给自己封装的每个方法加上这个异常捕捉装饰器,如果调用的封装方法报错了,就会进入这个装饰器,捕捉到指定异常后,我会刷新页面,再次执行刚刚报错的封装方法,然后会记录一次失败日志
-
日志:一般自己封装的方法都希望有日志,那如果每个封装的方法里单独调用日志类就会显得很臃肿重复,所以可以用一个日志装饰器代替
-
前置操作:比如多个方法执行前都需要调用同一个方法,那可以将依赖方法写在装饰器中
-
后置操作:比如每次执行方法后都需要还原数据集,可以将清理操作写在装饰器中
-
权限校验:执行方法前先进行权限校验,校验通过才会允许执行方法
-
性能测试
单例模式如何编写
def singleton(cls):
_instance = {}
def inner():
if cls not in _instance:
_instance[cls] = cls()
return _instance[cls]
return inner
@singleton
class Cls(object):
def __init__(self):
pass
cls1 = Cls()
cls2 = Cls()
print(id(cls1) == id(cls2))
---
class Singleton(object):
def __init__(self, cls):
self._cls = cls
self._instance = {}
def __call__(self):
if self._cls not in self._instance:
self._instance[self._cls] = self._cls()
return self._instance[self._cls]
@Singleton
class Cls2(object):
def __init__(self):
pass
cls1 = Cls2()
cls2 = Cls2()
print(id(cls1) == id(cls2))