python中的命名空间
Python中的namespace大致有三种:
- local namespace: 作用范围为当前函数或者类方法
- global namespace: 作用范围为当前模块
- build-in namespace: 作用范围为所有模块
当函数/方法、变量等信息发生重名时,Python会按照 “local namespace -> global namespace -> build-in namespace”的顺序搜索用户所需元素,并且以第一个找到此元素的 namespace 为准。
同时,Python中的内建函数locals()和globals()可以用来查看不同namespace中定义的元素。
Python闭包
在python中,所谓方法也是一个变量罢了。简单说,闭包就是根据不同的配置信息得到不同的结果。专业的解释:闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。
def greeting_conf(prefix):
def greeting(name):
print prefix, name
return greeting
mGreeting = greeting_conf("Good Morning")
mGreeting("Wilber")
mGreeting("Will")
在上面代码中greeting_conf似乎已经执行完了,但是他的参数却存活了下来。所以,这个函数对象存活到什么时候,他的参数就存活到什么时候。实现原理是外部函数有一个__closure__属性,当内部函数调用外部函数变量时,就会把传给自己的变量存储在这个属性当中。通过这一机制,可以将这个变量的声明延长到和外部函数声明一样长。
python装饰器
python的装饰器类似于java注解,提供对函数和类的增强。python装饰器是一个语法糖,也就是其实际功能在编译阶段就已经完成。
class Coordinate(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "Coord: " + str(self.__dict__)
def add(a, b):
return Coordinate(a.x + b.x, a.y + b.y)
def sub(a, b):
return Coordinate(a.x - b.x, a.y - b.y)
one = Coordinate(100, 200)
two = Coordinate(300, 200)
def wrapper(func):
def checker(a, b): # 1
if a.x < 0 or a.y < 0:
a = Coordinate(a.x if a.x > 0 else 0, a.y if a.y > 0 else 0)
if b.x < 0 or b.y < 0:
b = Coordinate(b.x if b.x > 0 else 0, b.y if b.y > 0 else 0)
ret = func(a, b)
if ret.x < 0 or ret.y < 0:
ret = Coordinate(ret.x if ret.x > 0 else 0, ret.y if ret.y > 0 else 0)
return ret
return checker
add = wrapper(add)
sub = wrapper(sub)
python装饰器的相关细节
@classmethod和@staticmethod就是两个装饰器。
@staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。
@staticmethod的使用场景是,有时候我们就需要一段和该类的所有属性完全无关的功能函数,比如说一个纯粹的日期格式转换函数。
除了上述几个装饰器外,python还在带@property的功能,可以方便的实现setter和getter的功能。