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---

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