python 模块与包的引用及移动绑定
""" 注意只要是调用模块,就是创建新名称空间,并在此新的名称空间下执行原模块文件里定义的所有代码
多模块导入,可以逗号来分 (import re,sys )
可以为模块定义别名咯 import spam as pi ,调用时就用pi.名字
1.为源文件(spam模块)创建新的名称空间,在spam中定义的函数和方法若是使用到了global时访问的就是这个名称空间。
2.在新创建的命名空间中执行模块中包含的代码
3.创建名字spam来引用该命名空间
4 事实上函数定义也是“被执行”的语句,模块级别函数定义的执行将函数名放入模块全局名称空间表,用globals()可以查看
print(globals())
'__name__': '__main__', '__cached__': None, 'getMoney': <function getMoney at 0x00000000007D0268>,
'getFunc': <function getFunc at 0x00000000007D01E0>, '__builtins__': <module 'builtins' (built-in)>,
'money': 1000, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000000000044C3C8>}
模块调用
A. import spam,会将源文件的名称空间'spam'带到当前名称空间中,使用时必须是spam.名字的方式(注意中import 后的那个名字 如果有点,则点左边只能是包名)
B. from 语句相当于import,也会创建新的名称空间,但是将spam中的名字直接导入到当前的名称空间中, 在当前名称空间中,直接使用名字就可以了
(注意啊,from 后面紧接只能包名,然后import名字不能有点啊,只能是名字 (当前有重名getMoney或者getFunc,那么会有覆盖效果)
支持别名:from spam import getMoney as gm from spam import * 把spam中所有的不是以下划线(_)开头的名字都导入到当前位置, 大部分情况下我们的python
程序不应该使用这种导入方式,因为*你不知道你导入什么名字, 很有可能会覆盖掉你之前已经定义的名字。而且可读性极其的差,在交互式环境中导入时没有问题 # """
1 #spam.py 2 print('from module spam ') 3 money = 1000 4 y = 100 5 def getMoney(): 6 print('get-->spam -->getmoney') 7 print(money) 8 def getFunc(): 9 getMoney() 10 def change(): 11 print('get->spam-->change') 12 global money 13 money = 0 14 print("当前money :%s"%money) 15 #可以使用__all__来控制*(用来发布新版本) 16 __all__= ['getMoney','money','y'] 17 #这样在另外一个文件中用from spam import *就这只能导入列表中规定的两个名字而不是全部
#testspam.py如下 :
1 import spam 2 money = 1118 3 spam.getMoney() 4 spam.getFunc() 5 spam.change()
输出结果
from module spam
get-->spam -->getmoney
1000
get-->spam -->getmoney
1000
get->spam-->change
当前money :0
练习:
要求一:保证包keystone可以在任意位置被导入
要求二:import keystone,然后就可以直接调用keystone.create和keystone.UserAuthInfo
1 创建如下目录结构 2 keystone/ 3 ├── __init__.py 4 └── auth 5 ├── __init__.py 6 └── plugins 7 └── core.py 8 9 core.py内容为:
1 def create(cls, auth_payload, method_name):
2 pass
3 class UserAuthInfo:
4 def __init__(self):
5 self.password = None
6 print('hello i core--->userauthinfo--->init')
文件目录结构:
1 #plugins/__init__.py
2 from . import core
3 print('auth-->plugins-->init')
1 #keystone/__init__.py
2 from .auth.plugins.core import create
3 from .auth.plugins.core import UserAuthInfo
1 #auth/__init__.py 2 from . import plugins
下面来测试:
1 import os,sys
2 base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
3 print(base_dir)
4 sys.path.append(base_dir)
5 # from aaaaa import keystone
6 import keystone
7 keystone.create(keystone.UserAuthInfo,'gi','ddd')
8 keystone.UserAuthInfo()
结果:
auth-->plugins-->init
hello i core--->userauthinfo--->init
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
如何基于移动方式绑定:
1 import os,sys
2 base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
3 #添加包的查找路径
4 sys.path.append(base_dir)
5 from aaaaa import keystone #从新路么下引入这个包
6 # import keystone
7 keystone.create(keystone.UserAuthInfo,'gi','ddd')
8 keystone.UserAuthInfo()
注意:其实只要知道__init__.py巧用,不管模块藏哪,都可以找到那个对应模块。