[012]Python的函數_模塊和包_全棧基礎

您好!此筆記的文本和代碼以網盤形式分享於文末!

因個人能力有限,錯誤處歡迎大家交流和指正!基礎部分內容簡單,但多且零散!

python之路——模塊和包
模塊定義:模塊是一個包含所有你定義的函數和變量的文件,其後綴名是.py
import加載的模塊分爲四個通用類別:
        1 使用python編寫的代碼(.py文件)
  2 已被編譯爲共享庫或DLL的C或C++擴展
  3 包好一組模塊的包
  4 使用C編寫並鏈接到python解釋器的內置模塊
模塊可以包含可執行的語句和函數的定義,這些語句的目的是初始化模塊,它們只在模塊名第一次遇到導入import語句時才執行
每個模塊都是一個獨立的名稱空間,定義在這個模塊中的函數,把這個模塊的名稱空間當做全局名稱空間,不用擔心我們定義在自己模塊中全局變量會在被導入時,與使用者的全局變量衝突
爲源文件(my_module模塊)創建新的名稱空間,在my_module中定義的函數和方法若是使用到了global時訪問的就是這個名稱空間。
.在新創建的命名空間中執行模塊中包含的代碼,見初始導入import my_module
用法 栗子 結果
mymodule代碼 print('from the my_module.py')

money = 1000


def read1():
    print('my_module->read1->money',money)


def read2():
    print('my_module->read2 calling read1')
    read1()


def change():
    global money
    money = 0
 
模塊的獨立名稱空間 # 模塊測試
import mymodule

# 變量、函數的獨立名稱空間
money = 10
print(money)
print(mymodule.money)
print(money)

mymodule.change()
print(money)
print(mymodule.money)


# 函數名相同測試
def read1():
    print('======')


mymodule.read1()
read1()
from the my_module.py
10
1000
10
10
0
my_module->read1->money 0
======
模塊的別名 # 模塊別名
import mymodule as mym

print(mym.money)
from the my_module.py
1000
據用戶輸入選擇模塊 # 根據輸入選擇不同的模塊
db_type = input('mysql or oracle: ')
if db_type == 'mysql':
    import mysqltest as db
elif db_type == 'oracle':
    import oracletest as db

db.sqlparse()
mysql or oracle: mysql
from mysql sqlparse
選擇讀取不同的模塊 # if file_format == 'xml':
#      import xmlreader as reader
# elif file_format == 'csv':
#      import csvreader as reader
# data = reader.read_date(filename)
 
一行中導入多個模塊 # 一行中導入多個模塊
# import sys,os,re
 
from導入
仍然是使用模塊的
命名空間
# from 導入
from mymodule import read1
money = 15
read1()
from the my_module.py
my_module->read1->money 1000
from導入
函數調用
仍然是使用模塊中的函數
from mymodule import read2


def read1():
    print('********')


read2()
from the my_module.py
my_module->read2 calling read1
my_module->read1->money 1000
覆蓋關係 from mymodule import read1


def read1():
    print('********')


read1()
from the my_module.py
********
變量賦值的綁定關係 from mymodule import money, read1
money = 100  # 將當前位置的名字money綁定到了100
print(money)  # 打印當前的名字
read1()  # 讀取my_module.py中的名字money,仍然爲1000
from the my_module.py
100
my_module->read1->money 1000
from導入的重命名
和導入多個
# 支持as
from mymodule import read1 as read
# 支持導入多行
from mymodule import (read1, read2, money)
 
from my_module import *  把my_module中所有的不是以下劃線(_)開頭的名字都導入到當前位置 缺點:造成誤覆蓋和可讀性差
from my_module import *  優化 __all__=['money','read1'] #這樣在另外一個文件中用from my_module import *就這能導入列表中規定的兩個名字  
模塊的循環引用    
模塊的加載與修改 def func1():
    print('func1')

import time,importlib
import aa
 
time.sleep(20)
# 等待期間修改aa.py中的內容
# importlib.reload(aa)
aa.func1()
 
將模塊作爲腳本執行 當做腳本運行:
__name__ 等於'__main__'
當做模塊導入:
__name__= 模塊名
def fib(n):  
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

if __name__ == "__main__":
    print(__name__)
    num = input('num :')
    fib(int(num))
 
模塊搜索路徑    
查找模塊中定義的名字 import my_module
dir(my_module)
3.4  模塊的搜索路徑
編譯python文件:爲了提高加載模塊的速度,解釋器會在__pycache__目錄中下緩存每個模塊編譯後的版本.pyc文件
你可以使用-O或者-OO轉換python命令來減少編譯模塊的大小
     - O 轉換會幫你去掉assert語句

-OO轉換會幫你去掉assert語句和__doc__文檔字符串
在速度上從.pyc文件中讀指令來執行不會比從.py文件中讀指令執行更快,只有在模塊被加載時,.pyc文件纔是更快的
dir()不會列舉出內建函數或者變量的名字 import builtins
dir(builtins)
 
包是一種通過使用‘.模塊名’來組織python模塊名稱空間的方式。
凡是在導入語句中(而不是在使用時)遇到帶點的,都要第一時間提高警覺:這是關於包纔有的導入語法
包是目錄級的(文件夾級),文件夾是用來組成py文件(包的本質就是一個包含__init__.py文件的目錄)
產生名稱空間中的名字來源於文件,import 包,產生的名稱空間的名字同樣來源於文件,即包下的__init__.py,導入包本質就是在導入該文件
在python3中,即使包下沒有__init__.py文件,import 包仍然不會報錯
創建包的目的不是爲了運行,而是被導入使用,記住,包只是模塊的一種形式而已,包即模塊
模塊  最重要是 自定義模塊
包的絕對路徑和相對路徑
包的引用和 特點
用法 栗子 結果
創建一個包 # 創建包
import os
os.makedirs('glance/api')
os.makedirs('glance/cmd')
os.makedirs('glance/db')

l = []
l.append(open('glance/__init__.py', 'w'))
l.append(open('glance/api/__init__.py', 'w'))
l.append(open('glance/api/policy.py', 'w'))
l.append(open('glance/api/versions.py', 'w'))
l.append(open('glance/cmd/__init__.py', 'w'))
l.append(open('glance/cmd/manage.py', 'w'))
l.append(open('glance/db/__init__.py', 'w'))
l.append(open('glance/db/models.py', 'w'))
map(lambda f: f.close(), l)
 
import 用法 # 當前文件與glance同級別的中測試
import glance.db.models
glance.db.models.register_models('mysql')

from models.py:  mysql
form import 用法 # import導入的模塊明確且不能帶點
from glance.db import models
models.register_models('mysql')

from glance.db.models import register_models
register_models('mysql')

from models.py:  mysql
from models.py:  mysql
__init__.py文件 # __init__.py文件 第一次導入包或者是包的任何其他部分,
# 都會依次執行包下的__init__.py文件
# 修改glance下 init文件 查看執行
from glance.db import models
models.register_models('mysql')
form glance __init__.py File
from models.py:  mysql
from glance.api import * 的用法 # 該語句只會導入包api下__init__.py文件中定義的名字,
# 可以在這個文件中定義__all___
"""
#在api文件夾下__init__.py中定義
x=10

def func():
    print('from api.__init.py')

__all__=['x','func','policy']
"""
# 使用import * 的用法 但是versions 依然是不能使用的
from glance.api import *
policy.get()
form glance __init__.py File
from policy.py
 絕對導入和相對導入 # 絕對導入和相對導入
"""
包內文件互掉,
注意事項和優缺點
    絕對導入:以glance作爲起始
    相對導入:用.或者..的方式最爲起始
    (只能在一個包中使用,不能用於不同目錄內)
"""
# 在glance/api/version.py 文件中
# # 絕對導入
# from glance.cmd import manage
# manage.main()
#
# # 相對導入
# from ..db import models
# models.register_models('db')
# 測試結果 與glance同級文件
from glance.api import versions
# # 導入自定義的子模塊時,應該使用form……import
# # 絕對或者相對導入,且包的相對導入只能用from的形式。
form glance __init__.py File
from manage.py
from models.py:  db
絕對路徑問題 看視頻  欠  
相對路徑問題 看視頻  欠  
單獨導入包 # 單獨導入包
# 單獨導入包名稱時不會導入包中所有包含的所有子模塊
import glance
glance.cmd.manage.main()
form glance __init__.py File
Traceback (most recent call last):
  # 解決辦法
"""
#在glance/__init__.py中添加
from . import cmd

#在glance/cmd/__init__.py中添加
from . import manage
"""
import glance
glance.cmd.manage.main()
form glance __init__.py File
from manage.py
python軟件開發
目錄結構規範
# python軟件開發目錄結構規範
import os
# bin/  存放項目的一些可執行文件
os.makedirs('soft/bin')
# conf/  配置文件
os.makedirs('soft/conf')
# core/  存放項目的所有源代碼(核心代碼)
# 1>源代碼中的所有模塊、包都應該放在此目錄。不要置於頂層目錄。
os.makedirs('soft/core')
# core/tests/ 子目錄 存放單元測試代碼;
os.makedirs('soft/core/tests')
# db/ 數據庫文件
os.makedirs('soft/db')
# lib/ 庫文件,放自定義模塊和包
os.makedirs('soft/lib')
# log/ 日誌文件
os.makedirs('soft/log')
# docs/ 存放一些文檔
os.makedirs('soft/doc')

l = []

# README 是項目說明文件
l.append(open('soft/README', 'w'))
l.append(open('soft/__init__.py', 'w'))
 
  # start 寫啓動程序
l.append(open('soft/bin/start.py', 'w'))
l.append(open('soft/bin/__init__.py', 'w'))

# setting 寫相關配置
l.append(open('soft/conf/setting.py', 'w'))
l.append(open('soft/conf/__init__.py', 'w'))
# my_log_setting 存放logging配置文件
l.append(open('soft/conf/my_log_setting.py', 'w'))
# config.ini 存放配置文件
l.append(open('soft/conf/config.ini', 'w'))
# main 程序的入口,存放核心邏輯代碼
l.append(open('soft/core/main.py', 'w'))
l.append(open('soft/core/__init__.py', 'w'))

# 存放單元測試代碼
l.append(open('soft/core/tests/test.main.py', 'w'))
l.append(open('soft/core/tests/__init__.py', 'w'))

# 寫數據庫文件
l.append(open('soft/db/db.json', 'w'))

# 存放常用功能
l.append(open('soft/lib/common.py', 'w'))
l.append(open('soft/lib/__init__.py', 'w'))

# 存放日誌
l.append(open('soft/log/all.log', 'w'))
map(lambda f: f.close(), l)
 

願有更多的朋友,在網頁筆記結構上分享更邏輯和易讀的形式:

鏈接:暫無
提取碼:暫無

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