python 包、模块

一、模块导入和使用

模块
在Python中,模块是代码组织的一种方式,把功能相近的 函数或者类 放到一个文件夹中,一个文件(.py)就是一个模块(module)
模块名就是文件名去掉后缀py。
这样做的好处是:
- 提高代码的可复用、可维护性。一个模块编写完毕后,可以很方便的在其它项目中导入
- 解决了命名冲突,不同模块中相同的命名不会冲突
常用的标准库:
|标准库        |说明              |
|-------------|------------------|
|builtins     |内建函数默认加载    |
|math         |数学库             |
|random       |生成随机数          |
|time         |时间               |
|datetime     |时间和日期          |
|calender     |日历               |
|hashlib      |加密算法            |
|copy         |拷贝                |
|functools    |常用的工具           |
|os           |操作系统接口         |
|re           |字符串正则匹配       |
|sys          |Python自身的运行环境 |
|multiprocessing|多线程            |
|threading    |多线程              |
|json         |编码和解码JSON对象   |
|logging      |记录日志,调试       |
1、自定义模块
2、使用系统一些模块

导入模块:
1、import  模块名
    模块名.变量  模块名.函数  模块名.类
2、from 模块名 import 变量 | 函数 | 类
    在代码中可以直接使用变量、函数、类
3、from 模块名 import *
    该模块中所有的内容
    但是如果想限制获取的内容,可以在模块中使用__all__ = [使用*可以访问的内容]
4、无论是import还是from的形式,都会将模块内容进行加载
    如果不希望其进行调用,就会用到__name__

    在自己的模块里面__name__叫: __main__
    在其它模块中通过导入的方式调用的话:__name__:模块名
自定义calculate.py模块

#变量
__all__ = ['add', 'number', 'Calculate']

number = 100
name = 'calculation'

#函数
def add(*args):
    if len(args) > 1:
        sum = 0
        for i in args:
            sum += i
        return sum
    else:
        print("至少传入两个参数...")
        return 0

def minus(*args):
    if len(args) > 1:
        m = 0
        for i in args:
            m -= i
        return m
    else:
        print("至少传入两个参数...")
        return 0

def devide(*args):
    pass

def multiple(*args):
    pass

#类
class Calculate:
    def __init__(self, num):
        self.num = num

    def test(self):
        print("正在使用Calculate进行运算", self.num)

    @classmethod
    def test1(cls):
        print("------> Calculate 类方法")

def test():
    print('我是测试')

if __name__ == '__main__':
    print(__name__)  #__name__ ---> __main__
    test()
test.py  使用calculate.py模块

#导入calculate模块  import 模块名
import calculate

list1 = [4, 2, 7, 8, 9]

#使用模块中的函数  模块名.变量  模块名.函数  模块名.类
result = calculate.add(*list1)
print(result)

#使用模块变量
print(calculate.number)

#使用模块中类
cal = calculate.Calculate(88)
cal.test()

#使用模块中类方法
calculate.Calculate.test1()

from calculate import add, number, Calculate

result = add(*list1)
print(result)
result += number
print(result)

c = Calculate(80)
c.test()

from calculate import *

result = add(*list1)
print(result)

result += number
print(result)

c = Calculate(80)
c.test()

 

二、包的导入

文件夹       包
非py文件     包:py文件

一个包中可以存放多个模块
项目 > 包 > 模块 > 类 函数 变量

 

pycharm集成开发环境中:

新建文件夹:右键——Directory——文件夹         如果要将文件夹改为包,则在包中新建__init__.py文件

新建包:右键——Python Package——新建文件夹,并在文件夹中新建了__init__.py文件

新建包 user,包中创建模块 model.py

__all__ = ['User']  #只是针对 from 包.模块 import *

version = '1.1'

class User:
    def __init__(self, username, password):
        self.username = username
        self.password = password

    def login(self, username, password):
        if username == self.username and password == self.password:
            print("登录成功")
        else:
            print("登录失败")

    def publish_article(self, article):
        print(self.username, '发表了文章:', article.name)

    def show(self):
        print(self.username, self.password)
新建包 article包,在包中新建 models.py 模块

class Article:
    def __init__(self, name, author):
        self.name = name
        self.author = author

    def show(self):
        print("发表文章名字:{}作者是:{}".format(self.name, self.author))

class Tag:
    def __init__(self, name):
        self.name = name

模块和包的导入调用:

article
    models.py
    __init__.py
    ...
user
    models.py
    __init__.py
    ...    
package.py

from 包 import 模块
from 包.模块 import 类、函数、变量
from 包.模块 import *
在package.py 中导入包

#导入 user 包中的 models 模块
#使用包中的模块中的User类
from user import models

u = models.User('admin', '123')
u.show()

#导入 user包中models 模块中的 User 类
from user.models import User

u = User('admin', '123456')
u.show()

#导入 article包中models 模块 的Article类
from article.models import Article

a = Article('个人总结', '姓名')
a.show()
一个包中 导入同级模块 或 不同包模块
例如:user 包中 test.py


'''
article
        models.py
        __init__.py
        ...
    user
        models.py
            User
        __init__.py
        test.py
'''

# 用户发表文章
# 创建用户对象
from user.models import User
from article.models import Article
# from .models import User  #.模块  当前目录下的models里面的User类  类似相对路径

user = User('admin', '123')  #--->user就是通过导入User类创建的

# 发表文章,文章对象
article = Article('个人总结', '作者')
user.publish_article(article)

list1 = [1, 2, 3]

#上方创建的 calculate 模块,导入add方法
from calculate import add
result = add(*list1)
print(result)

 

三、包的__init__文件

__init__.py文件
当导入包的时候,默认调用__init__.py文件
作用:
1、当导入包的时候,把一些初始化的函数、变量、类定义在__init__.py文件中
2、此文件中的函数,变量等的访问,只需要通过包名.函数/变量/类
3、结合__all__=[通过 * 可以访问的模块

包中__init__.py 中 __all__ = ['', '']  包中可以暴露的模块,其它文件可以导入本包的哪些模块

包中模块xxx.py 中的 all = ['', ''']  知识针对本模块可以导入的类、函数、属性

user 包中 __init__.py

__all__ = ['models']  #向外暴露什么模块,__init__是控制当前包,哪些模块可以导入

print('-----> user的init')

def create_app():
    print("---> create —— app")

def printA():
    print('--->AAAAAAAAA')
user包中 models 模块

__all__ = ['User']  #只是针对 from 包.模块 import *

version = '1.1'

class User:
    def __init__(self, username, password):
        self.username = username
        self.password = password

    def login(self, username, password):
        if username == self.username and password == self.password:
            print("登录成功")
        else:
            print("登录失败")

    def publish_article(self, article):
        print(self.username, '发表了文章:', article.name)

    def show(self):
        print(self.username, self.password)

 使用:

在package_init.py 文件中导入 user 包 或 导入user包中models模块的User类

import user
from user.models import User

user.create_app()
user.printA()
package_init.py

#from 模块 import *  表示可以使用模块里面的所有内容,如果没有定义__all__ ,所有都可以访问,但是如果添加了__all__=[],只有列表中的内容可以访问

#from 包 import *  表示该包中内容(模块)是不能完全访问的,就需要在__init__.py文件中定义__all__ = [可以通过*访问的模块]
from user import *

user = models.User('admin', '123')
user.show()

 

四、模块的循环导入

大型python项目中,需要很多python.py(模块)文件,由于架构不当,可能会出现模块间相互引用的情况

循环导入
A: A模块
    def test():
        f()

B: B模块
    def f():
        test()

避免产生循环导入:
1、重新架构    造成成本过大、工作量过大
2、将导入的语句放到函数中
3、将导入语句放到模块的最后
loop.py

from loop2 import func

def task1():
    print('---> task1')

def task2():
    print('---> task2')
    func()

if __name__ == '__main__':  #自己调用执行,其它导入的不执行
    task1()
    task2()
loop2.py

def func():
    print("---循环导入2里面的func---")
    from loop import task1
    task1()
    print("---循环导入2里面的func---")

输出:

---> task1
---> task2
---循环导入2里面的func---
---> task1
---循环导入2里面的func---

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章