Python的模块引用和查找路径(2)

那么如何引用pet.py这个模块呢?按照Python的约定,需要在animal文件夹中创建名为__init__.py的空文本文件,以标识animal文件夹是一个包。倘若animal文件夹内还有文件夹作为包,也必须包含__init__.py文件。这样就层层标识了访问的路径。

>>> import animal.pet
This pet
>>> print animal.pet.name
This pet
>>> animal.pet.run("everywhere")
This pet runs everywhere
>>>

或者使用from关键字直接导入模块内的属性或方法:

>>> from animal.pet import name,run
>>> print name
This pet
>>> run("everywhere")
This pet runs everywhere
>>>

三、Python模块间引用

简答来说,只要Python模块在其执行环境配置的搜索路径中,并且其所在位置是包结构的一部分,那么我们就可以引用该模块。上文已经提供了模块引用的基本示例。只不过模块间引用时import语句是写在模块文件中,我们修改person.py模块的代码。

1、from、import和as

# -*- coding: utf-8 -*-

ID = 1
name =  "This person"
print name

def say(something):
    print name,'says', something

from animal.pet import name as pet_name, run as pet_run

def have():
    print name,'has', pet_name

import语句可以写在文档中的任何位置,甚至if语句中,以便更好的控制模块引用。还可以通过as语句,使用另一个变量名进行引用,以避免变量名冲突。

>>> import person
This person
This pet
>>> print person.name
This person
>>> print person.pet_name
This pet
>>> person.have()
This person has This pet
>>>

2、*通配符

上面的import代码明确了引用的变量名,但如果想引用模块中所有变量可以使用*通配符,将上面的import语句改写如下:

from animal.pet import *

但这样有可能造成变量名冲突,如下name变量发生冲突,覆盖了person自己的name变量的值:

>>> import person
This person
This pet
>>> print person.name
This pet

但如果想用*通配符,又不想引用模块中的所有变量,可以在模块中用变量__all__进行限制,修改pet.py,限制只引用ID和run两个变量名。

# -*- coding: utf-8 -*-
__all__ = ['ID','run']

ID = 2
name =  "This pet"
print name

def run(somewhere):
    print name,'runs', somewhere

因为没有引用pet模块中的name变量,person的name变量值没有改变,run却可以调用了。

>>> import person
This person
This pet
>>> print person.name
This person
>>> person.run("nowhere")
This pet runs nowhere
>>>

3、引用包

上面都是引用具体的animal.pet模块,但是这对于一个相对独立且拥有众多的模块的包来说就显得麻烦了,可以直接import animal吗?答案是肯定的,但是Python不像C#引用dll或者java引用jar那样,引用后包内的模块就可以通过命名空间直接访问了(在访问控制许可下)。默认情况下Python还是需要导入包内的具体模块的,但有个变通的办法,就是使用包中__init__.py文件,提前准备包内需要被引用的各个模块中的变量,类似于向外部引用者暴露包内接口。__init__.py文件代码是在包或者包内模块被引用时执行的,因而可以在其中做一些初始化的工作。修改animal文件夹中__init__.py文件如下,其中模块可以使用绝对路径和相对路径,相对路径中一个句点.代表同级目录,两个句点..代表父目录。

print "__init__"

from pet import name as pet_name, run as pet_run
#from animal.pet import name as pet_name, run as pet_run
#from .pet import name as pet_name, run as pet_run
 

修改person.py,直接引用anmial包:

# -*- coding: utf-8 -*-

ID = 1
name =  "This person"
print name

def say(something):
    print name,'says', something

import animal

def have():
    print name,'has', pet_name

在Python环境中引用person模块,person引用animal,并自动执行__init__的代码加载相关变量,通过dir方法可以查看模块中的变量,其中两个下划线开始的变量每个模块都有,这些变量具有特殊的作用,是Python预定义的。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/297857a8c9e7f4c5d0be7949ac5d0c25.html