Python课程第六天作业

1.以自己的理解总结为什么会出现循环导入,并用代码举例说明

循环导入报错并不是应为相互之间引用而导致报错,实际上是在导入一个模块时发现引用的模块不存在
示例如下:
m1.py
from m2 import m2
def m1():
    a=m2

m2.py
from m1 import m1
def m2():
    b=m1
执行任意一个文件,报如下错误
Traceback (most recent call last):
  File "C:/code/untitled/第六天/m1.py", line 1, in <module>
    from m2 import m2
  File "C:codeuntitled第六天m2.py", line 1, in <module>
    from m1 import m1
  File "C:codeuntitled第六天m1.py", line 1, in <module>
    from m2 import m2
ImportError: cannot import name 'm2'

2.如何来解决循环导入,并解决第1题中的循环导入问题

1.直接import导入
m1.py
import m2
def m1():
    a=m2.m2

m2.py
from m1 import m1
def m2():
    b=m1
    
2.延迟导入
from m2 import m2
m1.py
def m1():
    a=m2
    
m2.py    
def m2():
    b=m1
from m1 import m1  

3.函数中导入
m1.py
from m2 import m2
def m1():
    a=m2
m1()

m2.py
def m2():
    from m1 import m1
    b=m1
4.拆成不循环引用(建议)
    代码略 
    
总结:
解决循环import的方法主要有几种:
1.延迟导入(lazy import)或函数导入
即把import语句写在方法或函数里面,将它的作用域限制在局部。
这种方法的缺点就是会有性能问题。
2.将from xxx import yyy改成import xxx;xxx.yyy来访问的形式

3.组织代码
出现循环import的问题往往意味着代码的布局有问题。
可以合并或者分离竞争资源。
合并的话就是都写到一个文件里面去。
分离的话就是把需要import的资源提取到一个第三方文件去。
总之就是将循环变成单向。
 

3.完成housework.py文件,拥有三个功能:sweep、wash、cook,自定义功能实现(函数体),从文件自执行和作为模块使用两方面,验证三个功能,且两方面使用方式可以共存

#!/usr/bin/env python
#  -*- coding: utf-8 -*-
def sweep():
    print('开始打扫')

def wash():
    print('开始洗衣')

def cook():
    print('开始做饭')

def main():
    sweep()
    wash()
    cook()

if __name__ == '__main__':
    print('开始做家务:')
    main()

4.导入模块的搜索路径有哪些?它们的优先级是?

1. 程序主目录,执行程序是包含执行代码文件的目录,交互模式下为当前工作目录,优先级最高
2. PYTHONPATH(sys.path)中的目录
3. 标准链接库目录,就是python的安装目录,源码在里面
4. 3.x 中可以用.pth 文件

5.现有一个run.py运行文件,与run文件同级目录下有一个pgk文件夹,文件夹下有两个模块m1、m2,m1模块内有功能f1,可以打印字符串"我是m1模块",
m2模块内有功能f2,可以打印字符串"我是m2模块",在run文件中,通过绝对路径方式导入m1模块,验证功能,在模块m1中通过相对路径导入m2模块,验证功能

run.py
from m1 import f1
f1()

m1.py
from six_day.test.m2 import f2
def f1():
    print('我是M1模块')

if __name__ == '__main__':
    f2()

6.建立如下包结构,完成包的使用

    结构:
    1)包名为pkg
    2)一级目录pkg下:
        -- m.py 模块 有函数m_fn
        -- sub1 子包
        -- sub2 子包
    3)二级目录sub1下:
        -- m1.py 模块 有函数 m1_fn
    4)二级目录sub2下:
        -- m2.py 模块 有函数 m2_fn
    要求:
    1)在执行文件run.py只导入pkg包,不做其他导入操作
    2)在执行文件run.py中访问三个函数的方式分别是
        pgk.m_fn()
        pgk.m1_fn()
        pgk.sub2.m2_fn()
    如何来设计包

 目录图:

├── pkg
│   ├── __init__.py
│   └── pkg
│       ├── __init__.py
│       ├── m.py
│       ├── sub1
│       │   ├── __init__.py
│       │   └── m1.py
│       └── sub2
│           ├── __init__.py
│           └── m2.py
└── run.py

各文件内容:

pkg/__init__.py:
from .pkg.m import m_fn
from .pkg.sub1.m1 import m1_fn
from .pkg import sub2

pkg/pkg/m.py :
def m_fn():
    print('我是 m_fn 模块')

pkg/pkg/sub1/m1.py:
def m1_fn():
    print('我是 m1_fn 模块')

pkg/pkg/sub2/__init__.py:
from .m2 import m2_fn

pkg/pkg/sub2/m2.py:
def m2_fn():
    print('我是 m2_fn 模块')

run.py:
import  pkg
pkg.m_fn()
pkg.m1_fn()

注意事项:

1.导包的以.开头的语法,属于包内语法,因为存在.语法开头的导包文件,都不能自执行
2.导包的以.开头的语法,只能和 from 结合使用
3.在包中的任意模块中都可以使用.语法访问包中其他模块中的名字
4.包中.代表当前目录,再添加一个.也就是..代表上一级目录



原文地址:https://www.cnblogs.com/panwenbin-logs/p/10880823.html