Hướng dẫn how do i run a python module from another directory? - làm cách nào để chạy một mô-đun python từ một thư mục khác?

Trong Python 3.4 trở lên, bạn có thể nhập trực tiếp từ tệp nguồn (liên kết đến tài liệu). Đây không phải là giải pháp đơn giản nhất, nhưng tôi bao gồm câu trả lời này cho sự hoàn chỉnh.

Đây là một ví dụ. Đầu tiên, tệp được nhập, được đặt tên là

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()
1:

def announce():
    print("Imported!")

Mã nhập tệp ở trên, được truyền cảm hứng rất nhiều bởi ví dụ trong tài liệu:

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()

Đầu ra:


['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!

Lưu ý rằng tên biến, tên mô -đun và tên tệp không cần phải khớp. Mã này vẫn hoạt động:

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

baz = module_from_file("bar", "/path/to/foo.py")

if __name__ == "__main__":
    print(baz)
    print(dir(baz))
    baz.announce()

Đầu ra:


['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!

Lưu ý rằng tên biến, tên mô -đun và tên tệp không cần phải khớp. Mã này vẫn hoạt động:

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()
9

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
1


['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
2

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
3

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
4

D :\projects\base
|__main.py   
|__app:
      |__modules
           |___mod.py

D :\projects\base
|__main.py   
|__app:
      |__modules
           |___mod.py
0

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
3
D :\projects\base
|__main.py   
|__app:
      |__modules
           |___mod.py
2

Các mô -đun chỉ đơn giản là một tệp python .py mà chúng ta có thể sử dụng các chức năng, lớp, biến trong một tệp khác. Để sử dụng những thứ này trong một tệp khác, trước tiên chúng ta cần nhập mô -đun đó vào tệp đó. Nếu mô -đun tồn tại trong cùng một thư mục với tệp, chúng ta có thể trực tiếp nhập nó bằng cách sử dụng cú pháp nhập mô -đun_name. Nhưng nếu nó tồn tại trong một thư mục khác, chúng ta không thể trực tiếp nhập nó. Trong bài viết này, chúng tôi sẽ thảo luận về nhiều cách khác nhau trong đó các mô -đun có thể được nhập từ bên ngoài thư mục.

mod.py:

Python

Cây thư mục của chúng tôi sẽ như sau:

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()
4
import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()
5
import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()
6
import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()
7
import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()
8

Chúng tôi có một thư mục có tên ‘cơ sở trong các dự án D: \ và trong thư mục cơ sở, chúng tôi có một thư mục có tên là ứng dụng. Thư mục cơ sở chứa main.py mà chúng tôi sẽ nhập mô -đun. Thư mục ứng dụng chứa một thư mục khác có tên các mô -đun chứa mod.py là mô -đun cần được nhập.

Chúng tôi sẽ giữ mã của cả hai tệp đơn giản nhất có thể để giải thích tốt hơn:

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()
2
import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()
3

Python

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()
9

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
0


['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
1

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
2

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
3

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()
9

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
5


['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
6

Output:

hello geeks!

Phương pháp 2: Sử dụng sys.path.insert ().

Như chúng ta đã thảo luận, Sys.Path chứa danh sách tất cả các thư mục sẽ được tìm kiếm mô -đun. Một cách tốt hơn là chèn thư mục của mô -đun ở vị trí 1 để nó được tải với mức độ ưu tiên cao hơn, từ đó giúp tránh một số xung đột tên. Mã của Main.py cho phương thức này sẽ là:

Python

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()
9

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
8


['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
9
import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

baz = module_from_file("bar", "/path/to/foo.py")

if __name__ == "__main__":
    print(baz)
    print(dir(baz))
    baz.announce()
0
import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

baz = module_from_file("bar", "/path/to/foo.py")

if __name__ == "__main__":
    print(baz)
    print(dir(baz))
    baz.announce()
1

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
2

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
3

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()
9

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
5


['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
6

Output:

hello geeks!

Phương pháp 2: Sử dụng sys.path.insert ().

Như chúng ta đã thảo luận, Sys.Path chứa danh sách tất cả các thư mục sẽ được tìm kiếm mô -đun. Một cách tốt hơn là chèn thư mục của mô -đun ở vị trí 1 để nó được tải với mức độ ưu tiên cao hơn, từ đó giúp tránh một số xung đột tên. Mã của Main.py cho phương thức này sẽ là:

D :\projects\base
|__main.py 
|__app:
|      |__modules
|          |___mod.py
|          |___init__.py
|__main.py

Hướng dẫn how do i run a python module from another directory? - làm cách nào để chạy một mô-đun python từ một thư mục khác?

Cách chúng tôi gọi cho mô -đun trong câu lệnh nhập là chúng tôi đi từ thư mục ứng dụng sang tệp mod và tách từng biến đường dẫn bằng một ‘.Bây giờ để nhập mod.py trong main.py từ phương thức này, mã trong main.py sẽ là:

Python

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()
9
import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

baz = module_from_file("bar", "/path/to/foo.py")

if __name__ == "__main__":
    print(baz)
    print(dir(baz))
    baz.announce()
8

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

baz = module_from_file("bar", "/path/to/foo.py")

if __name__ == "__main__":
    print(baz)
    print(dir(baz))
    baz.announce()
9

Output:

hello geeks!

Phương pháp 4: Sử dụng thư viện nhập

Chúng tôi cũng có thể nhập một mô -đun từ một thư mục bên ngoài bằng thư viện nhập.Đối với điều này, trước tiên chúng tôi sẽ phải nhập mô -đun nhập khẩu.util.Sau đó, hãy gọi phương thức nhập khẩu.util.spec_from_file_location () có 2 đối số file_name và file_path, trả về một giá trị.Giá trị này sẽ được sử dụng với phương thức nhập khẩu.util.module_from_spec () để nhập một mô -đun với một tên cụ thể.Sau đó, chúng ta có thể sử dụng tên cụ thể này để gọi các hàm, lớp, biến của mô -đun.

Python

import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()
9
import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

baz = module_from_file("bar", "/path/to/foo.py")

if __name__ == "__main__":
    print(baz)
    print(dir(baz))
    baz.announce()
8

Phương pháp 4: Sử dụng thư viện nhập


['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
5

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
6
import importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

baz = module_from_file("bar", "/path/to/foo.py")

if __name__ == "__main__":
    print(baz)
    print(dir(baz))
    baz.announce()
1

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
8

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!
9

Chúng tôi cũng có thể nhập một mô -đun từ một thư mục bên ngoài bằng thư viện nhập.Đối với điều này, trước tiên chúng tôi sẽ phải nhập mô -đun nhập khẩu.util.Sau đó, hãy gọi phương thức nhập khẩu.util.spec_from_file_location () có 2 đối số file_name và file_path, trả về một giá trị.Giá trị này sẽ được sử dụng với phương thức nhập khẩu.util.module_from_spec () để nhập một mô -đun với một tên cụ thể.Sau đó, chúng ta có thể sử dụng tên cụ thể này để gọi các hàm, lớp, biến của mô -đun.

D :\projects\base
|__main.py   
|__app:
      |__modules
           |___mod.py
3

D :\projects\base
|__main.py   
|__app:
      |__modules
           |___mod.py
4

Output:

hello geeks!