Modul Python3


Dalam bab sebelumnya, kami menggunakan penterjemah Python untuk memprogramkan skrip kami Jika anda keluar dan kemudian memasukkan penterjemah Python, semua kaedah dan pembolehubah yang anda tentukan akan hilang.

Untuk tujuan ini, Python menyediakan cara untuk menyimpan definisi ini dalam fail untuk digunakan oleh beberapa skrip atau contoh penterjemah interaktif Fail ini dipanggil modul.

Modul ialah fail yang mengandungi semua fungsi dan pembolehubah yang anda takrifkan, dan akhirannya ialah .py. Modul boleh diimport oleh program lain untuk menggunakan fungsi dan fungsi lain dalam modul. Ini juga dilakukan menggunakan perpustakaan standard python.

Berikut ialah contoh menggunakan modul daripada perpustakaan standard python.

#!/usr/bin/python3
# 文件名: using_sys.py

import sys

print('命令行参数如下:')
for i in sys.argv:
   print(i)

print('\n\nPython 路径为:', sys.path, '\n')

Hasil pelaksanaan adalah seperti berikut:

$ python using_sys.py 参数1 参数2
命令行参数如下:
using_sys.py
参数1
参数2


Python 路径为: ['/root', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
  • 1 import sys memperkenalkan modul sys.py dalam pustaka standard python; modul tertentu.

  • 2. sys.argv ialah senarai yang mengandungi parameter baris arahan.

  • 3.sys.path mengandungi senarai laluan yang penterjemah Python mencari modul yang diperlukan secara automatik.


penyataan import

Jika anda ingin menggunakan fail sumber Python, cuma laksanakan pernyataan import dalam fail sumber lain Sintaksnya adalah seperti berikut:

import module1[, module2[,... moduleN]

Apabila jurubahasa menemui pernyataan import, modul akan diimport jika ia berada dalam laluan carian semasa.

Laluan carian ialah senarai semua direktori yang akan dicari oleh jurubahasa dahulu. Jika anda ingin mengimport modul sokongan, anda perlu meletakkan arahan di bahagian atas skrip:

support.py Kod fail ialah:

#!/usr/bin/python3
# Filename: support.py

def print_func( par ):
    print ("Hello : ", par)
    return

test.py Perkenalkan modul sokongan :

#!/usr/bin/python3
# Filename: test.py
 
# 导入模块
import support
 
# 现在可以调用模块里包含的函数了
support.print_func("php")

Hasil output contoh di atas:

$ python3 test.py 
Hello :  php

Sesuatu modul hanya akan diimport sekali, tidak kira berapa kali anda melaksanakan import. Ini menghalang modul yang diimport daripada dilaksanakan berulang kali.

Apabila kami menggunakan pernyataan import, bagaimanakah jurubahasa Python mencari fail yang sepadan?

Ini melibatkan laluan carian Python. Laluan carian terdiri daripada satu siri nama direktori Jurubahasa Python mencari modul yang diimport daripada direktori ini.

Ini kelihatan seperti pembolehubah persekitaran Malah, laluan carian juga boleh ditentukan dengan mentakrifkan pembolehubah persekitaran.

Laluan carian ditentukan apabila Python disusun atau dipasang, dan ia juga harus diubah suai apabila memasang perpustakaan baharu. Laluan carian disimpan dalam pembolehubah laluan dalam modul sys Untuk melakukan percubaan mudah, dalam penterjemah interaktif, masukkan kod berikut:

>>> import sys
>>> sys.path
['', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
>>>

sys.path Output ialah senarai di mana item pertama berada. kosong Rentetan '' mewakili direktori semasa (jika ia dicetak daripada skrip, anda boleh melihat dengan lebih jelas direktori mana itu), iaitu direktori tempat kita melaksanakan penterjemah python (untuk skrip, ia adalah direktori tempat skrip berjalan terletak).

Jadi jika, seperti saya, terdapat fail dengan nama yang sama dengan modul yang akan diimport dalam direktori semasa, modul yang akan diimport akan disekat.

Selepas memahami konsep laluan carian, anda boleh mengubah suai sys.path dalam skrip untuk memperkenalkan beberapa modul yang tiada dalam laluan carian.

Sekarang, buat fail fibo.py dalam direktori semasa penterjemah atau direktori dalam sys.path Kodnya adalah seperti berikut:

# 斐波那契(fibonacci)数列模块

def fib(n):    # 定义到 n 的斐波那契数列
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

def fib2(n): # 返回到 n 的斐波那契数列
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result

Kemudian masukkan penterjemah Python dan gunakan arahan berikut untuk mengimport modul ini:

>>> import fibo

Ini tidak menulis nama fungsi yang ditakrifkan secara langsung dalam fibo ke dalam jadual simbol semasa, tetapi hanya menambah modul fibo The nama tertera di situ.

Fungsi boleh diakses menggunakan nama modul:

>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'

Jika anda merancang untuk menggunakan fungsi dengan kerap, anda boleh memberikannya nama tempatan:

>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377


dari...import pernyataan

Python dari pernyataan membenarkan anda mengimport bahagian tertentu daripada modul ke dalam ruang nama semasa Sintaks adalah seperti berikut:

from modname import name1[, name2[, ... nameN]]

Sebagai contoh, untuk mengimport. fungsi fibo fib modul, gunakan pernyataan berikut:

from fibo import fib

Pengisytiharan ini tidak akan mengimport keseluruhan modul fib ke dalam ruang nama semasa, ia hanya akan memperkenalkan satu fibonacci dalam fib ke dalam jadual simbol global modul yang melaksanakan pengisytiharan ini.



Dari...import* pernyataan

Ia juga mungkin untuk mengimport semua kandungan modul ke dalam ruang nama semasa, hanya gunakan pernyataan berikut:

from modname import *

Ini menyediakan cara mudah untuk mengimport semua projek dalam modul. Walau bagaimanapun, kenyataan ini tidak boleh digunakan secara berlebihan.


Modul mendalam

Selain definisi kaedah, modul juga boleh menyertakan kod boleh laku. Kod ini biasanya digunakan untuk memulakan modul ini. Kod ini hanya akan dilaksanakan pada kali pertama ia diimport.

Setiap modul mempunyai jadual simbol bebas sendiri, yang digunakan sebagai jadual simbol global untuk semua fungsi dalam modul.

Jadi, pengarang modul boleh menggunakan pembolehubah global ini dengan selamat di dalam modul tanpa perlu risau tentang mengacaukan pembolehubah global pengguna lain.

Sebaliknya, jika anda benar-benar tahu apa yang anda lakukan, anda juga boleh mengakses fungsi dalam modul melalui notasi seperti modname.itemname.

modul boleh mengimport modul lain. Menggunakan import pada permulaan modul (atau skrip, atau tempat lain) untuk mengimport modul, sudah tentu, hanya konvensyen, bukan keperluan. Nama modul yang diimport akan diletakkan dalam jadual simbol modul yang sedang beroperasi.

Terdapat juga kaedah import Anda boleh menggunakan import untuk mengimport terus nama (fungsi dan pembolehubah) dalam modul ke dalam modul operasi semasa. Contohnya:

>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

Kaedah import ini tidak akan meletakkan nama modul yang diimport dalam jadual aksara semasa (jadi dalam contoh ini, nama fibo tidak ditakrifkan).

Terdapat cara lain untuk mengimport semua (fungsi, pembolehubah) nama dalam modul ke dalam jadual aksara modul semasa sekaligus:

>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

Ini akan mengimport semua nama yang Diimport, kecuali nama bermula dengan satu garis bawah (_). Dalam kebanyakan kes, pengaturcara Python tidak menggunakan kaedah ini kerana pengenalan nama daripada sumber lain mungkin akan menimpa definisi sedia ada.


__name__ attribute

Apabila modul pertama kali diperkenalkan oleh program lain, program utamanya akan dijalankan. Jika kita mahu blok program tertentu dalam modul tidak dilaksanakan apabila modul diimport, kita boleh menggunakan atribut __name__ untuk membuat blok program dilaksanakan hanya apabila modul itu sendiri dijalankan.

#!/usr/bin/python3
# Filename: using_name.py

if __name__ == '__main__':
   print('程序自身在运行')
else:
   print('我来自另一模块')

Keluaran yang sedang berjalan adalah seperti berikut:

$ python using_name.py

Program itu sendiri sedang berjalan

$ python
>>> import using_name
我来自另一模块
>>>

Penjelasan: Setiap modul mempunyai atribut __name__ Apabila nilainya ialah '__main__', ia menunjukkan bahawa modul itu sendiri sedang berjalan diimport.


fungsi dir()

内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回:
</p>
<pre>
>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)  
['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__',
 '__package__', '__stderr__', '__stdin__', '__stdout__',
 '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe',
 '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv',
 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder',
 'call_tracing', 'callstats', 'copyright', 'displayhook',
 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix',
 'executable', 'exit', 'flags', 'float_info', 'float_repr_style',
 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags',
 'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit',
 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
 'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path',
 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1',
 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit',
 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout',
 'thread_info', 'version', 'version_info', 'warnoptions']

Jika tiada parameter diberikan, fungsi dir() akan menyenaraikan semua nama yang ditakrifkan pada masa ini:

>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir() # 得到一个当前模块中定义的属性列表
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
>>> a = 5 # 建立一个新的变量 'a'
>>> dir()
['__builtins__', '__doc__', '__name__', 'a', 'sys']
>>>
>>> del a # 删除变量名a
>>>
>>> dir()
['__builtins__', '__doc__', '__name__', 'sys']
>>>

Standard modules

Python sendiri dilengkapi dengan beberapa perpustakaan modul standard, yang akan diperkenalkan dalam dokumen rujukan perpustakaan Python (iaitu, "Dokumen Rujukan Perpustakaan" kemudian).

Sesetengah modul dibina terus ke dalam penghurai Walaupun ini bukan fungsi terbina dalam sesetengah bahasa, ia boleh digunakan dengan sangat cekap, malah panggilan peringkat sistem tidak menjadi masalah.

Komponen ini akan dikonfigurasikan dengan cara yang berbeza mengikut sistem pengendalian yang berbeza Contohnya, modul winreg hanya akan disediakan untuk sistem Windows.

Perlu diingatkan bahawa terdapat sys modul khas yang dibina ke dalam setiap penghurai Python. Pembolehubah sys.ps1 dan sys.ps2 mentakrifkan rentetan yang sepadan dengan gesaan utama dan gesaan sekunder:

>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print('Yuck!')
Yuck!
C>

Pakej

Pakej ialah cara untuk mengurus Borang ruang nama modul Python, mengambil "nama modul titik".

Sebagai contoh, nama modul ialah A.B, kemudian ia mewakili submodul B dalam pakej A.

Sama seperti semasa menggunakan modul, anda tidak perlu risau tentang pengaruh bersama pembolehubah global antara modul yang berbeza Menggunakan format nama modul titik, anda tidak perlu risau tentang pertindihan nama modul antara perpustakaan yang berbeza.

Dengan cara ini, pengarang yang berbeza boleh menyediakan modul NumPy atau perpustakaan grafik Python.

Andaikan anda ingin mereka bentuk modul (atau panggil ia sebagai "pakej") yang mengendalikan fail bunyi dan data dengan cara yang bersatu.

Terdapat banyak format fail audio yang berbeza (pada asasnya dibezakan dengan nama akhiran, seperti: .wav, :file:.aiff, :file:.au,), jadi anda perlu mempunyai set pemalar Ditambah modul untuk menukar antara format yang berbeza.

Dan terdapat banyak operasi berbeza untuk data audio ini (seperti mencampurkan, menambah gema, menambah fungsi penyama, mencipta kesan stereo buatan), jadi anda memerlukan satu set modul yang anda tidak boleh selesai menulis operasi ini.

Berikut ialah struktur pakej yang mungkin (dalam sistem fail hierarki):

sound/                          顶层包
      __init__.py               初始化 sound 包
      formats/                  文件格式转换子包
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  声音效果子包
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  filters 子包
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

Apabila mengimport pakej, Python akan berdasarkan direktori dalam sys.path Cari subdirektori yang terkandung dalam pakej ini . Direktori

hanya akan dikenali sebagai pakej jika ia mengandungi fail yang dipanggil __init__.py Ini terutamanya untuk mengelakkan beberapa nama klise (seperti rentetan) daripada menjejaskan modul yang sah dalam laluan carian.

Dalam kes paling mudah, letakkan kosong :file:__init__.py. Sudah tentu, fail ini juga boleh mengandungi beberapa kod permulaan atau memberikan nilai kepada pembolehubah __all__ (akan diperkenalkan kemudian).

Pengguna hanya boleh mengimport modul tertentu dalam satu pakej pada satu masa, contohnya:

import sound.effects.echo

Ini akan mengimport submodul: mod:song.effects.echo. Dia mesti menggunakan nama penuhnya untuk mengakses:

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

Terdapat juga cara untuk mengimport submodul:

from sound.effects import echo

Ini juga akan mengimport submodul: mod:echo, dan ia tidak memerlukan awalan yang panjang itu, jadi ia boleh digunakan seperti ini:

echo.echofilter(input, output, delay=0.7, atten=4)

Satu lagi variasi ialah mengimport terus fungsi atau pembolehubah:

from sound.effects.echo import echofilter

Begitu juga, kaedah ini akan mengimport submodul :mod:echo, dan anda boleh terus menggunakan fungsi :func:echofilter:

echofilter(input, output, delay=0.7, atten = 4)

Perhatikan bahawa apabila menggunakan daripada item import pakej, item yang sepadan boleh menjadi submodul (subpakej) dalam pakej, atau nama lain yang ditakrifkan dalam pakej, seperti fungsi, kelas Atau pembolehubah.

Sintaks import akan terlebih dahulu menganggap item sebagai nama definisi pakej Jika ia tidak ditemui, ia akan cuba mengimportnya sebagai modul. Jika ia masih belum ditemui, tahniah, pengecualian :exc:ImportError telah dilemparkan.

Sebaliknya, jika anda menggunakan borang import seperti import item.subitem.subsubitem, kecuali item terakhir, semua mestilah pakej, dan item terakhir boleh menjadi modul atau pakej, tetapi ia tidak boleh menjadi kelas, nama fungsi atau pembolehubah.


Import * daripada pakej

Bayangkan apa yang akan berlaku jika kita menggunakan daripada sound.effects import *?

Python akan memasuki sistem fail, mencari semua submodul dalam pakej ini, dan mengimportnya satu demi satu.

Tetapi malangnya, kaedah ini tidak berfungsi dengan baik pada platform Windows, kerana Windows ialah sistem yang tidak peka huruf besar-kecil.

Pada platform jenis ini, tiada siapa yang berani menjamin bahawa fail yang dipanggil ECHO.py diimport sebagai modul :mod:echo atau :mod:Echo atau pun :mod:ECHO.

(Sebagai contoh, Windows 95 menjengkelkan menggunakan huruf pertama setiap fail) dan peraturan penamaan 8+3 DOS menjadikan masalah lebih rumit apabila berurusan dengan nama modul yang panjang.

Untuk menyelesaikan masalah ini, kami hanya boleh meminta pengarang pakej untuk menyediakan indeks pakej yang tepat.

Pernyataan import mengikut peraturan berikut: Jika fail definisi pakej __init__.py mempunyai pembolehubah senarai yang dipanggil __all__, maka apabila menggunakan daripada import pakej *, semua nama dalam senarai ini akan diimport sebagai kandungan pakej .


Sebagai pengarang pakej, jangan lupa pastikan __all__ juga dikemas kini selepas mengemas kini pakej. Awak kata saya tak akan buat ni, saya takkan guna import*, okay, tak apa, siapa yang jadikan awak bos. Berikut ialah contoh, file:sounds/effects/__init__.py mengandungi kod berikut:


__all__ = ["echo", "surround", "reverse"]

Ini bermakna apabila anda menggunakan daripada sound.effects import * ini Apabila menggunakan itu, anda hanya akan mengimport tiga submodul ini dalam pakej.

Jika __all__ adalah benar tetapi tidak ditakrifkan, maka menggunakan sintaks daripada import sound.effects * *tidak* akan mengimport sebarang submodul dalam pakej: mod:sound.effects. Ia hanya mengimport pakej :mod:sound.effects dan semua yang ditakrifkan di dalamnya (mungkin menjalankan kod permulaan yang ditakrifkan dalam :file:__init__.py).

Ini akan mengimport semua nama yang ditakrifkan dalam :file:__init__.py. Dan ia tidak akan memusnahkan semua modul yang dinyatakan secara eksplisit yang kami import sebelum ayat ini. Lihat bahagian kod ini:

import sound.effects.echo
import sound.effects.surround
from sound.effects import *

Dalam contoh ini, sebelum melaksanakan dari...import, modul gema dan sekeliling dalam package:mod:sound.effects diimport ke dalam ruang nama semasa. (Sudah tentu, tiada masalah jika __all__ ditakrifkan)

Biasanya kami tidak menganjurkan menggunakan * kaedah ini untuk mengimport modul, kerana kaedah ini sering menyebabkan kebolehbacaan kod berkurangan. Walau bagaimanapun, ini menjimatkan banyak ketukan kekunci, dan beberapa modul direka untuk diimport hanya melalui kaedah tertentu.

Ingat, anda tidak boleh tersilap menggunakan daripada Package import specific_submodule. Malah, ini adalah pendekatan yang disyorkan. Melainkan submodul yang anda ingin import mungkin mempunyai nama yang sama dengan submodul pakej lain.

Jika pakej ialah sub-pakej dalam struktur (seperti dalam contoh ini untuk pakej: mod:sound), dan anda ingin mengimport pakej adik-beradik (pakej tahap yang sama), anda perlu menggunakan laluan mutlak import untuk mengimport. Contohnya, jika modul :mod:sound.filters.vocoder mahu menggunakan modul :mod:echo daripada pakej :mod:sound.effects, anda akan menulis daripada sound.effects import echo.

from . import echo
from .. import formats
from ..filters import equalizer

Import relatif, sama ada tersirat atau eksplisit, bermula daripada modul semasa. Nama modul utama sentiasa "__main__". Modul utama aplikasi Python hendaklah sentiasa dirujuk menggunakan laluan mutlak. Pakej

juga menyediakan atribut tambahan, :attr:__path__. Ini ialah senarai direktori Setiap direktori yang disertakan di dalamnya mempunyai :file:__init__.py yang menyediakan pakej ini. Pembolehubah ini boleh diubah suai untuk mempengaruhi modul dan subpakej yang terkandung dalam pakej.

Fungsi ini tidak biasa digunakan dan biasanya digunakan untuk mengembangkan modul dalam pakej.