Python – Module

Trong phần này, chúng ta làm việc với các module Python. Một số ví dụ cách tạo và sử dụng các module Python.
Module là file code Python. Python module có đuôi file .py

Python code có để được quản lý theo:
– functions
– class
– module
– package

Các module Python được sử dụng để tổ chức code Python. Ví dụ: code liên quan đến cơ sở dữ liệu được đặt bên trong module cơ sở dữ liệu, code bảo mật trong module bảo mật, v.v. Các tập lệnh Python nhỏ hơn có thể là một module. Nhưng các chương trình lớn hơn được chia thành nhiều module. Các module được nhóm lại với nhau để tạo thành package.

Tên module

Module name là tên file với đuôi *.py. Ví dụ, file empty.py, empty là tên module.
Biến __name__ chứa tên của module đang được gọi. Module hiện tại đang được thực thi được gọi là module main, và giá trị biến __name__ của main module luôn có giá trị là ‘__main__’

Ví dụ 1: chúng ta có 2 file: empty.py và test_empty.py. Module thứ 2 là module main, import module ’empty’ module bằng cách sử dụng keyword ‘import’
empty.py

"""
An empty module
"""

test_empty.py

import empty
import sys

print(__name__)
print(empty.__name__)
print(sys.__name__)

Trong ví dụ này, chúng ta import 2 module: custom module ’empty’ và buit-in module ‘sys’ (built-in module là module đã được tích hợp sẵn trong Python).

Kết quả:
C:\Users\Dell>python test_empty.py
__main__
empty
sys

Tên main module ‘test_empty.py’ luôn là ‘__main__’. Để lấy tên module được import, sử dụng .__name__

Đường dẫn module

Khi module được import, trước tiên trình thông dịch tìm kiếm tên module trong build-in module. Nếu không tìm thấy, trình thông dịch tìm kiếm module name trong list đường dẫn được lưu trong biến sys.path. Biến sys.path là list string chứa các đường dẫn để tìm kiếm các module. Nó bao gồm current working directory (đường dẫn chứa module đang được thực thi), tên đường dẫn được chỉ định trong biến môi trường PYTHONPATH và thêm một vài đường dẫn phụ thuộc vào việc cài đặt thêm. Nếu không tìm thấy module, trình thông dịch raise ‘ImportError’

Ví dụ 2: In ra tất cả đường dẫn trong sys.path

import sys
import textwrap

sp = sorted(sys.path)
dnames = ', '.join(sp)

print(textwrap.fill(dnames))

Ví dụ này in ra tất cả đường dẫn trong sys.path

import textwrap

Module ‘textwrap’ được sử dụng để format lại đoạn văn bản cho dễ đọc hơn.

sp = sorted(sys.path)

Chúng ta lấy list đường dẫn từ ‘sys.path’ và sắp xếp chúng.

dnames = ', '.join(sp)

Tạo string chứa các đường dẫn phân tách nhau bởi dấu phẩy

Kết quả:
C:\Users\Dell>python test.py
C:\Users\Dell, C:\Users\Dell\AppData\Local\Programs\Python\Python37,
C:\Users\Dell\AppData\Local\Programs\Python\Python37\DLLs,
C:\Users\Dell\AppData\Local\Programs\Python\Python37\lib,
C:\Users\Dell\AppData\Local\Programs\Python\Python37\lib\site-
packages,
C:\Users\Dell\AppData\Local\Programs\Python\Python37\python37.zip

Keyword import

Keyword import được sử dụng theo nhiều cách khác nhau.

from module import *

Cấu trúc này sẽ import tất cả các định nghĩa Python vào namespace của module khác. Có 1 ngoại lệ là object bắt đầu với kí tự gạch chân (_) sẽ không được import. Các objects (function, biến,…) với tên bắt đầu bởi kí tự gạch chân được sử dụng nội bộ trong module.
=> Cách import này không được khuyến khích sử dụng.

Ví dụ 3: import *

from math import *

print(cos(3))
print(pi)

Ví dụ này import tất cả các định nghĩa trong module ‘math’. Module ‘math’ là built-in module. Chúng ta có thể gọi trực tiếp function mà không cần thông qua module name.

Kết quả:
C:\Users\Dell>python test.py
-0.9899924966004454
3.141592653589793

Việc sử dụng cấu trúc import * có thể dẫn đến ‘ô nhiễm’ namespace. Chúng ta có thể có nhiều object cùng tên và các object này có thể bị override.

Ví dụ 4: Override object

from math import *

pi = 3.14

print(cos(3))
print(pi)

Ví dụ này in ra màn hình console giá trị pi = 3.14. Đây có thể là giá trị không mong muốn vì đã bị override.
Vấn đề ‘ô nhiễm’ name space sẽ trở nên nghiêm trọng trong các project lớn.

Object không được import

Ví dụ 5: Object không được import
names.py

"""
names is a test module
"""

_version = 1.0

names = ["Paul", "Frank", "Jessica", "Thomas", "Katherine"]

def show_names():

    for i in names:
       print(i)

def _show_version():

    print(_version)

test_names.py

from names import *

print(locals())

show_names()

Biến _version và function _show_version không được import vào module test_names. Chúng ta không nhìn thấy trong namespace. Function locals trả về tất cả các định nghĩa trong module.

Kết quả:
C:\Users\Dell>python test_names.py
{‘__name__’: ‘__main__’, ‘__doc__’: None, ‘__package__’: None, ‘__loader__’: <_frozen_importlib_external.SourceFileLoader object at 0x0000016736A5DEB8>, ‘__spec__’: None, ‘__annotations__’: {}, ‘__builtins__’: , ‘__file__’: ‘test_names.py’, ‘__cached__’: None, ‘names’: [‘Paul’, ‘Frank’, ‘Jessica’, ‘Thomas’, ‘Katherine’], ‘show_names’: }
Paul
Frank
Jessica
Thomas
Katherine

Import specific object

Với keyword ‘from’ và ‘import’, chúng ta có thể chỉ import 1 vài object cần thiết.

from module import fun, var

Câu lệnh import này chỉ import object ‘fun’, ‘var’ từ ‘module’

Ví dụ 6: Import specific objects

from math import sin, pi

print(sin(3))
print(pi)

Import 2 object ‘sin’ và ‘pi’ từ module ‘math’

Ví dụ 7: Import specific objects

from names import _version, _show_version

print(_version)
_show_version()

Trong ví dụ này, chúng ta vẫn có thể import các object với tên bắt đầu bởi dấu gạch chân.
=> BAD PRACTICE

Kết quả:

C:\Users\Dell>python test.py
1.0
1.0

import module

import module

Cách import module này được sử dụng nhiều nhất. Nó không gây ra “ô nhiễm” namespace. Cách import này cho phép truy cập vào tất cả các định nghĩa trong module thông qua tên module .<định nghĩa>

Ví dụ 8: import module

import math

pi = 3.14

print(math.cos(3))
print(math.pi)
print(math.sin(3))
print(pi)

Trong ví dụ này, chúng ta gọi định nghĩa thông qua module name ‘math’. Như vậy, biến ‘pi’ và ‘math.pi’ là 2 biến hoàn toàn độc lập và có thể sử dụng cả 2, không xảy ra việc override.

Kết quả:
C:\Users\Dell>python test.py
-0.9899924966004454
3.141592653589793
0.1411200080598672
3.14

Alias module

Chúng ta có thể tạo alias cho module với keyword ‘as’
Ví dụ 9: Alias cho module

import math as m

print(m.pi)
print(m.cos(3))

Trong ví dụ này, chúng ta gán alias ‘m’ cho module ‘math’, có thể sử dụng alias ‘m’ để gọi các định nghĩa trong module ‘math’.

Kết quả:
C:\Users\Dell>python test.py
3.141592653589793
-0.9899924966004454

ImportError

Trình thông dịch raise ImportError, nếu không thể import module
Ví dụ 10: Không import được module

try:
    import empty2
except ImportError as e:
    print('Failed to import:', e)

Trong ví dụ này, không tồn tại module ’empty2′. Trình thông dịch raise ImportError.

Kết quả:
C:\Users\Dell>python test.py
Failed to import: No module named ’empty2′

Execute module

Module có thể được import vào module khác hoặc có thể thực thi module đó trực tiếp. Developer thường tạo script test để test các module được viết ra. Nếu chỉ module được thực thi trực tiếp, __name__ = ‘__main__’

Chúng ta sẽ minh họa thông qua ví dụ fibonacci module.

Ví dụ 11: Thực thi trực tiếp module
fibonacci.py

"""
A module containing the fibonacci
function.
"""

def fib(n):

    a, b = 0, 1
    
    while b < n:
    
        print(b, end=" ")
        (a, b) = (b, a + b)


# testing

if __name__ == '__main__':
    fib(500)

– Nếu thực thi trực tiếp module fibonacci, __name__ = ‘__main__’, fib(500) sẽ tự động được gọi
C:\Users\Dell>python fibonacci.py
1 1 2 3 5 8 13 21 34 55 89 144 233 377

– Nếu thực hiện import module ‘fibonacci’ vào module khác, thì __name__ = ‘fibonacci’, fib(500) sẽ không tự động được gọi
>>> import fibonacci as fib
>>> fib.fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 >>>

dir function

Function built-in dir() trả về list string đã được sắp xếp chứa tên được định nghĩa bởi module.
Ví dụ 12: built-in function dir()

"""
This is dirfun module 
"""

import math, sys

version = 1.0

names = ["Paul", "Frank", "Jessica", "Thomas", "Katherine"]

def show_names():
  
   for i in names:
      print(i)

print(dir())

Trong ví dụ này, chúng ta định nghĩa 2 built-in module: math và sys, biến, list và function.

print(dir())

Built-in dir() trả về tất cả các tên available trong namespace của module.

Kết quả:
C:\Users\Dell>python dirfun.py
[‘__annotations__’, ‘__builtins__’, ‘__cached__’, ‘__doc__’, ‘__file__’, ‘__loader__’, ‘__name__’, ‘__package__’, ‘__spec__’, ‘math’, ‘names’, ‘show_names’, ‘sys’, ‘version’]

Chúng ta có thể nhìn thấy built-in variable __file__, __name__ và các variable/function khác đã được define.

global function

Function globals() trả về dictionary mô tả biến global trong namespace
Ví dụ 13: Function globals()

import textwrap

version = 1.0

def myfun():
    pass

gl = globals()
gnames = ', '.join(gl)

print(textwrap.fill(gnames))

Sử dụng function globals() để in ra tất cả các global name trong module.

Kết quả:
C:\Users\Dell>python test.py
__name__, __doc__, __package__, __loader__, __spec__, __annotations__,
__builtins__, __file__, __cached__, textwrap, version, myfun, gl

Attribute __module__

Thuộc tính class ‘__module__’ có tên của module mà class được định nghĩa.
Ví dụ 14:
animals.py

"""
module animals
"""

class Cat:
    pass

class Dog:
    pass

mclass.py

from animals import Cat

class Being:
    pass
  
b = Being()
print(b.__module__)

c = Cat()
print(c.__module__)

Đoạn code này, chúng ta sử dụng thuộc tính ‘__module__’

from animals import Cat

Import class ‘Cat’ từ module animals.

class Being:
    pass

Định nghĩa class ‘Being’ trong current module ‘animals’

b = Being()
print(b.__module__)

Tạo instance của class ‘Being’, và in ra tên module của class ‘Being’

c = Cat()
print(c.__module__)

Tạo instance của class ‘Cat’ và in ra tên module của class ‘Cat’

Kết quả:
C:\Users\Dell>python mclass.py
__main__
animals

Từ kết quả ta thấy current module là ‘__main__’, module của class ‘Cat’ là ‘animals’

Be the first to comment

Leave a Reply