python 专题十一 基本知识

来源:互联网 发布:c语言case语句用法 编辑:程序博客网 时间:2024/04/25 22:47

命名空间

globals其实就是一个dict,可以直接添加项

locals()和globals()

在函数外部,locals() 和 globals() 作⽤用完全相同。⽽而当在函数内部调⽤用时,locals() 则是获取当前 函数堆栈帧的名字空间,其中存储的是函数参数、局部变量等信息

引用传递

对象总是按引⽤用传递,简单点说就是通过复制指针来实现多个名字指向同⼀一对象。因为 arena 也是 在堆上分配的,所以⽆无论何种类型何种⼤大⼩小的对象,都存储在堆上。Python 没有值类型和引⽤用类

如果不希望对象被修改,就需使⽤用不可变类型,或对象复制品。 不可变类型:int, long, str, tuple, frozenset

除了某些类型⾃自带的 copy ⽅方法外,还可以: • 使⽤用标准库的 copy 模块进⾏行深度复制。 • 序列化对象,如 pickle、cPickle、marshal

>>> import copy>>> x = object()>>> l = [x]! ! ! ! # 创建一个列表。>>> l2 = copy.copy(l)! ! # 浅复制,仅复制对象自身,而不会递归复制其成员。>>> l2 is l! ! ! ! # 可以看到复制列表的元素依然是原对象。False>>> l2[0] is xTrue>>> l3 = copy.deepcopy(l)!! # 深度复制,会递归复制所有深度成员。>>> l3 is l! ! ! ! # 列表元素也被复制了。False>>> l3[0] is xFalse

eval

>>> eval("(1 + 2) * 3")! ! # 假装看不懂这是啥……9>>> eval("{'a': 1, 'b': 2}")! # 将字符串转换为 dict。{'a': 1, 'b': 2}>>> x = 100>>> eval("x + 200")!! ! # 使⽤用当前上下文的名字空间。300>>> ns = dict(x = 10, y = 20)>>> eval("x + y", ns)! ! # 使用自定义名字空间。30>>> ns.keys()! ! ! # 名字空间里多了 __builtins__。['y', 'x', '__builtins__']

要执行代码片段,或者 PyCodeObject 对象,那么就需要动用 exec 。同样可以带入自定义名字空
间,以避免对当前环境造成污染。
>>> py = """... class User(object):... def __init__(self, name):... self.name = name... def __repr__(self):... return "<User: {0:x}; name={1}>".format(id(self), self.name)... """>>> ns = dict()>>> exec py in ns! ! ! # 执行代码片段,使用自定义的名字空间。>>> ns.keys()! ! ! # 可以看到名字空间包含了新的类型:User。['__builtins__', 'User']>>> ns["User"]("Tom")! ! # 完全可用。貌似用来开发 ORM 会很简单。<User: 10547f290; name=Tom>

继续看 exec 执行 PyCodeObject 的演示

>>> py = """... def incr(x):... global z... z += x... """>>> code = compile(py, "test", "exec")! ! ! # 编译成 PyCodeObject。>>> ns = dict(z = 100)! ! ! ! ! # ⾃自定义名字空间。>>> exec code in ns!! ! ! ! ! # exec 执⾏行以后,名字空间多了 incr。>>> ns.keys()! ! ! ! ! ! # def 的意思是创建⼀一个函数对象。['__builtins__', 'incr', 'z']>>> exec "incr(x); print z" in ns, dict(x = 50)! # 试着调⽤用这个 incr,不过这次我们提供⼀一个150! ! ! ! ! ! ! ! #! local 名字空间,以免污染 global。>>> ns.keys()! ! ! ! ! ! # 污染没有发⽣生。['__builtins__', 'incr', 'z']

bool

>>> map(bool, [None, 0, "", u"", list(), tuple(), dict(), set(), frozenset()])[False, False, False, False, False, False, False, False, False]

精度问题

>>> from decimal import Decimal, ROUND_UP, ROUND_DOWN>>> float('0.1') * 3 == float('0.3')! ! ! ! ! # float 转型精度不同False>>> Decimal('0.1') * 3 == Decimal('0.3')! ! ! ! # decimal 没有问题True>>> Decimal('2.675').quantize(Decimal('.01'), ROUND_UP)! ! # 精确控制 roundDecimal('2.68')>>> Decimal('2.675').quantize(Decimal('.01'), ROUND_DOWN)Decimal('2.67')

注释使用"""doc""",方便生成帮助信息

>>> def test():... """... func help... """... pass>>> test.__doc__'\n func help\n '>>> class User(object):... """User Model"""...... def __init__(self):... """user.__init__"""... pass>>> User.__doc__'User Model'>>> User.__init__.__doc__'user.__init__'

while

比我们熟悉的 while 多了个可选的 else 分支。如果循环没有被中断,那么 else 就会执行>>> x = 3>>> while x > 0:... x -= 1... else:... print "over!"over!>>> while True:... x += 1... if x > 3: break... else:... print "over!"

Generator

用一种优雅的方式创建列表、字典或集合。

>>> [x for x in range(10)]   # 列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]>>> {x for x in range(10)}   # 集合set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])>>> {c:ord(c) for c in "abc"}   # 字典{'a': 97, 'c': 99, 'b': 98}>>> (x for x in range(10))<generator object <genexpr> at 0x10328a690>可带上条件进⾏行过滤。>>> [x for x in range(10) if x % 2][1, 3, 5, 7, 9]或⽤用多个 for ⼦子句实现嵌套。>>> ["{0}{1}".format(c, x) for c in "abc" for x in range(3)]['a0', 'a1', 'a2', 'b0', 'b1', 'b2', 'c0', 'c1', 'c2']