pythonnamespace
Ⅰ python 中regular package 和 namesapce package的区别
regular package就是指常规模块,一般就是指python内置模块例如os,或者使用第三方的插件导入的模块,例如操作excel的xlrd.没有所处环境的区别.
namespace package 一般是指用户自己定义的,为了避免重名冲突,而进行划分的一种方式.也就是为了实现,在不同环境下,导入不同的模块,但是为了方便切换,在不同模块下具有相同变量名称.常用的情况如,在测试环境和生产环境下,导入定义数据库配置的全局变量,MYsql_SETTINGS,但是在不同环境下,它所对应的mysql数据库的配置时不同的.这时就可以通过namespace package来实现.将配置和代码进行解耦.
实现方式可以有:
不同环境下设置环境变量
程序加入运行参数,导入不同路径下的配置文件
等等
欢迎补充
Ⅱ python命名空间包导入算法
要理解命名空间包,需从底层去学习包导入操作在Python 3.3中是如何完成的。在导入过程中,3.3版本与3.2和之前的版本一样,依旧会遍历模块搜索路径sys.path中的每个目录。然而,在3.3版本中,当对每个模块搜索路径中的directory搜索名为spam的被导人包时,Python会按照下面的顺序测试一系列更广的匹配条件:
1.如果找到directory\spaml_init__.py,便会导入一个常规包并返回。
2.如果找到directoryspam.ipy,pyc,或其他模块扩展名},便会导人一个简单模块并
返回。
3.如果找到文件夹directorylspam,便会将其记录下来,而扫描将从搜索路径中的下一
个目录继续。
4.如果上述的所有都没有找到,扫描将从搜索路径中的下一个目录继续。
如果搜索路径扫描结束后没有从上述步骤1和步骤2中返回一个模块或包,而同时在上述步骤3中至少记录了一个路径,那么就会创建一个命名空间包。
命名空间包的创建会立即发生,而且不会推迟到一个子层级的导入发生之时。新的命名空间包有一个_path_属性,该属性被设置为在上述步骤3中扫描并记录的目录路径字符串的可迭代对象,但是没有_file_属性。
path_属性在随后更深的访问过程中用于搜索所有包组件。命名空间包的_path_中每个被记录的项目,都会在进一步嵌套的项目被请求时进行搜索,这很像一个常规包的单独路径。
从另一方面看,命名空间包的_path_属性对于更低层次组件的关系,和sys.path对于顶层最左侧的包导入路径的关系是一样的。命名空间包成为了访问更低层次项目的“父路径”,这一访问也使用了上面介绍的四个步骤。
最终的结果是一个命名空间包是一种对多个目录的虚拟拼接,这些目录可以位于多个sys.path项目中。然而一旦一个命名空间包被创建,它和一个常规包之间并没有功能上的区别,它能够支持我们所学过的常规包的一切功能,包括包相对导入语法。
Ⅲ Python之禅中的namespace怎么理解
什么时候分别用一、二、三是最佳实践?——这个问题没有特别的规定,只是看个人编码风格和习惯。
这三种的定义你应该明白,二和三是一样的,只是三用了一个通配符导入了模块中所有名字而已。
命名空间的本质就是采用更长的字符串来区分不同模块下可能同名的函数/类,然后为了减少写函数名/类名时候的麻烦,发明的一种可以认为是语法糖的东西。
在一个函数的 scope 的中再定义函数——我本人不常用这种做法,因为我是学C语言出身,一个函数的scope中再定义一个函数,我看到的唯一好处就是可以隐藏一些仅仅由这个函数使用而其他函数不使用的一些小函数,而且不用再传参数:
def fun(a, b):
def calc(): return a * b - a / b if a < b: return calc() if a >= b: return 1 + calc()
calc函数不用传参,方便使用,而且对外是隐藏的,这么奇葩的函数在fun外也没有人用,放到fun内部是比较合适的。当然,也不绝对,你可以爱怎么写怎么写。
Ⅳ Python 中作用域与命名空间的问题
i=2这一句是定义了一个局部变量i,并赋值为2;这个时候全局作用域的i会被屏蔽,所以全局变量i是没有被修改的所以结果是1;
访问全局变量时可以直接访问,但是修改全局作用域的时候一定要在赋值之前,进行如下声明:
deff():
globali
i=2
因为python里赋值语句和声明变量是一个体的,所以需要global来告诉解释器i是全局变量,接下来的i=2才能被当作是赋值
------------------追答---------------------
同一个代码块(作用域)里, 同一个变量的作用域只能是同一种或者说同一个变量只能来自同一个作用域, 不能是一会是局部变量然后又变成全局变量;
i = i + 1
首先前面的'i='表明了i是一个局部变量(没有global声明, 创建局部变量), 然后后面的'i+1'里的i自然也是局部变量(同一个函数下同一个变量,i已经是局部变量了, 不能再当作全局变量去用), 那么自然会报错, i在使用前未声明
i += 1
报错就更明显了, 没有global声明 那么再修改变量i的时候, 自然是当作局部变量, 使用前未声明
变量的查找顺序遵循 LEGB 可以自己网络
关于作用域给你再写个简单的示例, 你对照着理解一下
Ⅳ python命名空间是什么
在Python中,所有的名字都存在一个空间中,它们在该空间中存在和被操作——这就是命名空间。它就像一个盒子,每一个变量名字都对应装着一个对象。当查询变量的时候,会从该盒子里面找到相应的对象。
【定义】
名称到对象的映射。命名空间是一个字典的实现,键为变量名,值是变量对应的值。各个命名空间是独立没有关系的,一个命名空间中不能有重名,但是不同的命名空间可以重名而没有任何影响。
相关推荐:《Python教程》
【分类】
python程序执行期间会有2个或3个活动的命名空间(函数调用时有3个,函数调用结束后2个)。按照变量定义的位置,可以划分为以下3类:
Local,局部命名空间,每个函数所拥有的命名空间,记录了函数中定义的所有变量,包括函数的入参、内部定义的局部变量。
Global,全局命名空间,每个模块加载执行时创建的,记录了模块中定义的变量,包括模块中定义的函数、类、其他导入的模块、模块级的变量与常量。
Built-in,python自带的内建命名空间,任何模块均可以访问,放着内置的函数和异常。
【生命周期】
Local(局部命名空间)在函数被调用时才被创建,但函数返回结果或抛出异常时被删除。(每一个递归函数都拥有自己的命名空间)。
Global(全局命名空间)在模块被加载时创建,通常一直保留直到python解释器退出。
Built-in(内建命名空间)在python解释器启动时创建,一直保留直到解释器退出。
各命名空间创建顺序:python解释器启动 ->创建内建命名空间 -> 加载模块 -> 创建全局命名空间 ->函数被调用 ->创建局部命名空间
各命名空间销毁顺序:函数调用结束 -> 销毁函数对应的局部命名空间 -> python虚拟机(解释器)退出 ->销毁全局命名空间 ->销毁内建命名空间
python解释器加载阶段会创建出内建命名空间、模块的全局命名空间,局部命名空间是在运行阶段函数被调用时动态创建出来的,函数调用结束动态的销毁的。
Ⅵ Python语言中命名空间的使用
如果一个命名声明为全局的,那么对它的所有引用和赋值会直接搜索包含这个模块全局命名的作用域。如果要重新绑定最里层作用域之外的变量,可以使用 nonlocal 语句;如果不声明为 nonlocal,这些变量将是只读的(对这样的变量赋值会在最里面的作用域创建一个新的局部变量,外部具有相同命名的那个变量不会改变)。
通常,局部作用域引用当前函数的命名。在函数之外,局部作用域与全局使用域引用同一命名空间:模块命名空间。类定义也是局部作用域中的另一个命名空间。
重要的是作用域决定于源程序的意义:一个定义于某模块中的函数的全局作用域是该模块的命名空间,而不是该函数的别名被定义或调用的位置,了解这一点非常重要。另一方面,命名的实际搜索过程是动态的,在运行时确定的——然而,Python 语言也在不断发展,以后有可能会成为静态的“编译”时确定,所以不要依赖动态解析!(事实上,局部变量已经是静态确定了。)
Python 的一个特别之处在于:如果没有使用 global 语法,其赋值操作总是在最里层的作用域。赋值不会复制数据,只是将命名绑定到对象。删除也是如此:del x 只是从局部作用域的命名空间中删除命名 x 。事实上,所有引入新命名的操作都作用于局部作用域。特别是 import 语句和函数定义将模块名或函数绑定于局部作用域(可以使用 global 语句将变量引入到全局作用域)。
global 语句用以指明某个特定的变量为全局作用域,并重新绑定它。nonlocal 语句用以指明某个特定的变量为封闭作用域,并重新绑定它。
Ⅶ python运行报错 AttributeError: 'Namespace' object has no attribute 'image'
这要看你args是怎么写的。
如果你不理解什么是args,就写死路径好了。
Ⅷ Python中的命名空间是什么
编程语言中的命名空间简单来说就是一些词的集合,
同一个词在不同的命名空间会有不同的意思,
用一个词来做例子
“手纸”在中文这个命名空间是厕纸的意思,
而在日文这个命名空间是信的意思。
这个算是过分简化的说明了。
Ⅸ Python lxml所有与多个命名空间问题,怎么解决
有如下xml
<A xmlns="http://This/is/a/namespace">
<B>dataB1</B>
<B>dataB2</B>
<B>
<C>dataC</C>
</B>
</A>
其中的xmlns属性表示的是该xml的默认命名空间,该命名空间必须是一个url形式
查看xml的tag
#encoding=utf8
from lxml import etree
str_xml = """
<A xmlns="http://This/is/a/namespace">
<B>dataB1</B>
<B>dataB2</B>
<B>
<C>dataC</C>
</B>
</A>
"""
xml = etree.fromstring(str_xml)
for node in xml.iter():
print node.tag
结果为:
{http://This/is/a/namespace}A
{http://This/is/a/namespace}B
{http://This/is/a/namespace}B
{http://This/is/a/namespace}B
{http://This/is/a/namespace}C
可以看到,跟普通xml的tag相比每个tag前面都多出了一个命名空间
获取命名空间 .nsmap
from lxml import etree
str_xml = """
<A xmlns="http://This/is/a/namespace">
<B>dataB1</B>
<B>dataB2</B>
<B>
<C>dataC</C>
</B>
</A>
"""
xml = etree.fromstring(str_xml)
ns = xml.nsmap
print ns
print ns[None]
结果
{None: 'http://This/is/a/namespace'}
http://This/is/a/namespace
ns[None]获取的是默认命名空间,ns会显示所有的命名空间
获取有命名空间的节点内容
from lxml import etree
str_xml = """
<A xmlns="http://This/is/a/namespace">
<B>dataB1</B>
<B>dataB2</B>
<B>
<C>dataC</C>
</B>
</A>
"""
xml = etree.fromstring(str_xml)
ns = xml.nsmap[None]
ns = "{%s}" % ns
for item in xml.findall("{0}B/{0}C".format(ns)): #不能用xpath会出错
print item.text
结果
dataC
注意,在查找节点时,每一级节点都需要加上命名空间。而且测试时发现,findall可以正常查找到信息,而xpath会报错。
获取带命名空间节点的属性值
from lxml import etree
str_xml = """
<A xmlns="http://This/is/a/namespace">
<B b="123">dataB1</B>
<B>dataB2</B>
<B>
<C>dataC</C>
</B>
</A>
"""
xml = etree.fromstring(str_xml)
ns = xml.nsmap[None]
ns = "{%s}" % ns
item = xml.find(ns+"B")
print item.get("b")
print item.text
结果
123
dataB1
可以看到,获取属性时,不需要加命名空间,直接获取即可