【python】locals()、globals()与名字空间

名字空间

Python使用叫做名字空间的东西来记录变量的轨迹。名字空间只是一个字典,它的键字就是变量名,字典的值就是那些变量的值。实际上,名字空间可以象Python的字典一样进行访问。
在一个Python程序中的任何一个地方,都存在几个可用的名字空间。每个函数都有着自己的名字空间,叫做局部名字空间,它记录了函数的变量,包括函数的参数和局部定义的变量。每个模块拥有它自己的名字空间,叫做全局名字空间,它记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。还有就是内置名字空间,任何模块均可访问它,它存放着内置的函数和异常。

当一行代码要使用变量 x 的值时,Python会到所有可用的名字空间去查找变量,按照如下顺序:

1.局部名字空间 - 特指当前函数或类的方法。如果函数定义了一个局部变量x,Python将使用这个变量,然后停止搜索。
2. 全局名字空间 - 特指当前的模块。如果模块定义了一个名为x的变量,函数或类,Python将使用这个变量然后停止搜索。
3. 内置名字空间 - 对每个模块都是全局的。作为最后的尝试,Python将假设x是内置函数或变量。

locals和globals的区别

locals()是只读的。globals()不是。这里说的只读,是值对于原有变量的只读。其实还可以对locals()赋值的。
注意,locals()返回的是当前所在最小命名空间的局部变量的一个拷贝。比如说在一个函数中调用locals(),那么返回的将是这个函数内部的局部变量。记住,locals返回的变量都是原有变量的“拷贝”。

from module importimport module之间的不同。使用import module,模块自身被导入,但是它保持着自已的名字空间,这就是为什么你需要使用模块名来访问它的函数或属性(module.function)的原因。但是使用 from module import,实际上是从另一个模块中将指定的函数和属性导入到你自己的名字空间,这就是为什么你可以直接访问它们却不需要引用它们所来源的模块的原因。

使用locals()的例子

在类的编写中,__init__方法中常常有类似self.something = something的累赘代码,我们可以用locals()方法来自动初始化实例变量。
原先的代码是这样的:

def __init__(self, foo, bar, baz, boom=1, bang=2):
    self.foo = foo
    self.bar = bar
    self.baz = baz
    self.boom = boom
    self.bang = bang

下面是修改之后的代码:

# 定义抽取属性的辅助函数
def attributesFromDict(d):
    self = d.pop('self')
    for n, v in d.iteritems():
        setattr(self, n, v)

# __init__被缩减为一行
def __init__(self, foo, bar, baz, boom=1, bang=2):
    attributesFromDict(locals())

转载请注明作者Jason Ding及其出处
Github博客主页(http://jasonding1354.github.io/)
GitCafe博客主页(http://jasonding1354.gitcafe.io/)
CSDN博客(http://blog.csdn.net/jasonding1354)
简书主页(http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)
Google搜索jasonding1354进入我的博客主页

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值