Bạn có thể sử dụng dấu gạch ngang trong tệp Python khi cố gắng nhập chúng không?


149

Về cơ bản khi tôi có một tệp python như:

python-code.py

Và sử dụng:

import (python-code)

thông dịch viên cho tôi lỗi cú pháp.

Vài ý kiến ​​về việc làm thế nào đê sửa nó? Là dấu gạch ngang bất hợp pháp trong tên tập tin python?

Câu trả lời:


167

Bạn nên xem PEP 8 , Hướng dẫn về Phong cách cho Mã Python:

Tên Mô-đun Gói và Mô-đun nên có tên viết tắt, tất cả chữ thường. Dấu gạch dưới có thể được sử dụng trong tên mô-đun nếu nó cải thiện khả năng đọc. Các gói Python cũng nên có tên viết tắt, tất cả chữ thường, mặc dù việc sử dụng dấu gạch dưới không được khuyến khích.

Vì tên mô-đun được ánh xạ thành tên tệp và một số hệ thống tệp không phân biệt chữ hoa chữ thường và cắt ngắn, nên điều quan trọng là tên mô-đun được chọn là khá ngắn - đây không phải là vấn đề trên Unix, nhưng nó có thể là một vấn đề vấn đề khi mã được chuyển đến các phiên bản Mac hoặc Windows cũ hơn hoặc DOS.

Nói cách khác: đổi tên tập tin của bạn :)


75
vấn đề không liên quan gì đến phong cách, đó là lỗi cú pháp

4
Như được hiển thị bên dưới, có thể vẫn có một tệp có tên này, vì vậy hướng dẫn kiểu có liên quan rất nhiều.
Paolo Bergantino

5
Có thể rất hữu ích khi sử dụng dấu gạch nối trong thư mục Python và tên tệp khi bạn rõ ràng muốn ngăn chặn nhập. Ví dụ: trong (giả sử) một dự án Django, bạn có thể có các tập lệnh được viết bằng Python không thể đánh địa chỉ như các ứng dụng. Bạn có thể đặt chúng trong một thư mục như thế ops-scriptsvà biết rằng chúng không thể được nhập bằng cách sử dụng cách tiếp cận không gian tên gói thông thường. Hoặc một tập lệnh có thể được đặt tên stop-website.pycho một hiệu ứng tương tự. Bất kỳ trong số này vẫn có thể được nhập qua runpyvà một số phương pháp khác, nhưng điều này giúp tránh một số lỗi phổ biến.
Chris Johnson

Đổi tên một mô-đun có thể có vấn đề, đặc biệt nếu bạn đang dựa vào một tiêu chuẩn khác. Trong trường hợp của tôi, tôi đang sử dụng các tệp cgi python trong cgi-binthư mục (thực hiện unitttests trên chúng), đó là afaik khá chuẩn. Trừ khi bạn có một trường hợp hiếm hoi như thế này, chắc chắn đổi tên mô-đun của bạn nếu bạn có quyền kiểm soát nó.
NuclePeon

1
Tôi mới phát hiện ra rằng PyDev sẽ cho phép các tên thư mục có dấu gạch nối, nhưng sẽ không hiển thị các lớp và / hoặc các biến nội bộ trong các tệp .py có trong thư mục đó.
dùng5920660

122

Một điều khác cần lưu ý trong mã của bạn là nhập không phải là một chức năng. Vì vậy, import(python-code)nên import python-code, như một số người đã đề cập, được hiểu là "nhập mã trăn trừ", không phải những gì bạn dự định. Nếu bạn thực sự cần nhập một tệp có dấu gạch ngang trong tên của nó, bạn có thể thực hiện như sau ::

python_code = __import__('python-code')

Nhưng, như đã đề cập ở trên, điều này không thực sự được khuyến khích. Bạn nên thay đổi tên tệp nếu đó là thứ bạn kiểm soát.


@KevinAudman bạn có một ví dụ hoạt động về việc sử dụng lib nhập với tệp gạch nối không? Tôi đã thử và thất bại.
Tom Hale

@TomHale importlib.import_module ('abmodule-1') sẽ hoạt động. Nếu import_module của bạn không hoạt động, tôi nghĩ rằng nhập thông thường cũng không hoạt động.
Ian Lin

63

TLD

Dấu gạch ngang không phải là bất hợp pháp nhưng bạn không nên sử dụng chúng vì 3 lý do:

  1. Bạn cần cú pháp đặc biệt để nhập tệp có dấu gạch ngang
  2. Không ai mong đợi một tên mô-đun với một dấu gạch ngang
  3. Nó chống lại các khuyến nghị của Hướng dẫn phong cách Python

Nếu bạn chắc chắn cần nhập tên tệp bằng dấu gạch ngang, cú pháp đặc biệt là:

module_name = __import__('module-name')

Tò mò về lý do tại sao chúng ta cần cú pháp đặc biệt?

Lý do cho cú pháp đặc biệt là khi bạn viết import somenamebạn đang tạo một đối tượng mô-đun bằng mã định danh somename(để sau này bạn có thể sử dụng nó với ví dụ somename.funcname). Tất nhiên module-namekhông phải là một định danh hợp lệ và do đó cú pháp đặc biệt đưa ra một định danh hợp lệ.

Bạn không hiểu tại sao tên mô-đun không phải là định danh hợp lệ?

Đừng lo lắng - tôi cũng không. Đây là một mẹo để giúp bạn: Hãy nhìn vào dòng python này : x=var1-var2. Bạn có thấy một phép trừ ở bên phải của bài tập hoặc một tên biến với dấu gạch ngang không?

PS

Không có gì nguyên bản trong câu trả lời của tôi ngoại trừ những gì tôi coi là những thông tin có liên quan nhất từ ​​tất cả các câu trả lời khác ở một nơi


Tôi đang cố gắng sử dụng gói nhập khẩu này có dấu gạch nối trong đó. psycopg2_binary = import_module('psycopg2-binary'). Lỗi => ModuleNotFoundError: No module named 'psycopg2-binary'. Nhưng psycopg2-binaryđược cài đặt. Không có ý tưởng làm thế nào để bao gồm nó.
Mote Zart

Có lẽ đó là một vấn đề con đường. Nhìn vào chrisyeh96.github.io/2017/08/08/ Cách
ndemou

32

Vấn đề là đó python-codekhông phải là một định danh. Trình phân tích cú pháp xem đây là điểm pythontrừ code. Tất nhiên điều này sẽ không làm những gì bạn yêu cầu. Bạn sẽ cần sử dụng một tên tệp cũng là một định danh python hợp lệ. Hãy thử thay thế -bằng một dấu gạch dưới.


4
+1. Không bao giờ nghĩ rằng tên tệp của mã nguồn Python phải là một định danh hợp lệ, vì tên tệp sẽ được sử dụng để tham chiếu đến đối tượng mô-đun.
andy

5

Bạn có thể nhập nó thông qua một số __import__hack, nhưng nếu bạn chưa biết cách, bạn không nên. Tên mô-đun Python phải là tên biến hợp lệ ("định danh") - điều đó có nghĩa là nếu bạn có mô-đun foo_bar, bạn có thể sử dụng nó từ bên trong Python ( print foo_bar). Bạn sẽ không thể làm như vậy với một tên lạ ( print foo-bar-> lỗi cú pháp).


5

Trên Python 3, sử dụng import_module :

from importlib import import_module
python_code = import_module('python-code')

Tổng quát hơn

import_module('package.subpackage.module')

1

Mặc dù việc đặt tên tệp phù hợp là khóa học tốt nhất, nhưng nếu python-codekhông thuộc quyền kiểm soát của chúng tôi, việc sử dụng hack __import__tốt hơn là sao chép, đổi tên hoặc làm rối tung mã của các tác giả khác. Tuy nhiên, tôi đã thử và nó không hoạt động trừ khi tôi đổi tên tệp thêm .pyphần mở rộng. Sau khi xem tài liệu để tìm ra cách lấy một mô tả cho .py, tôi đã kết thúc với điều này:

import imp

try:
    python_code_file = open("python-code")
    python_code = imp.load_module('python_code', python_code_file, './python-code', ('.py', 'U', 1))
finally:
    python_code_file.close()

Nó tạo ra một tập tin mới python-codectrong lần chạy đầu tiên.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.