globals其实就是一个dict,可以直接添加项
在函数外部,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 x True >>> l3 = copy.deepcopy(l)!! # 深度复制,会递归复制所有深度成员。 >>> l3 is l! ! ! ! # 列表元素也被复制了。 False >>> l3[0] is x False
>>> 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__']
>>> 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']
>>> 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)! ! # 精确控制 round Decimal('2.68') >>> Decimal('2.675').quantize(Decimal('.01'), ROUND_DOWN) Decimal('2.67')
>>> 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 多了个可选的 else 分支。如果循环没有被中断,那么 else 就会执行 >>> x = 3 >>> while x > 0: ... x -= 1 ... else: ... print "over!" over! >>> while True: ... x += 1 ... if x > 3: break ... else: ... print "over!"
用一种优雅的方式创建列表、字典或集合。
>>> [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']