Những gì từ __future__ nhập tuyệt đối_import thực sự làm gì?

167
Two-Bit Alchemist 2015-11-17 10:18.

Tôi đã trả lời một câu hỏi liên quan đến việc nhập tuyệt đối bằng Python, mà tôi nghĩ rằng tôi đã hiểu được dựa trên việc đọc bảng thay đổi Python 2.5PEP đi kèm . Tuy nhiên, khi cài đặt Python 2.5 và cố gắng tạo ra một ví dụ về cách sử dụng đúng cách from __future__ import absolute_import, tôi nhận ra mọi thứ không quá rõ ràng.

Ngay từ bảng thay đổi được liên kết ở trên, tuyên bố này đã tóm tắt chính xác hiểu biết của tôi về thay đổi nhập khẩu tuyệt đối:

Giả sử bạn có một thư mục gói như thế này:

pkg/
pkg/__init__.py
pkg/main.py
pkg/string.py

Điều này xác định một gói có tên pkgchứa các mô-đun con pkg.mainpkg.string.

Hãy xem xét mã trong mô-đun main.py. Điều gì xảy ra nếu nó thực hiện câu lệnh import string? Trong Python 2.4 trở về trước, trước tiên nó sẽ tìm trong thư mục của gói để thực hiện nhập tương đối, tìm pkg / string.py, nhập nội dung của tệp đó dưới dạng pkg.stringmô-đun và mô-đun đó được liên kết với tên "string"trong pkg.mainkhông gian tên của mô-đun.

Vì vậy, tôi đã tạo cấu trúc thư mục chính xác này:

$ ls -R
.:
pkg/

./pkg:
__init__.py  main.py  string.py

__init__.pystring.pytrống rỗng. main.pychứa mã sau:

import string
print string.ascii_uppercase

Như mong đợi, chạy điều này với Python 2.5 không thành công với AttributeError:

$ python2.5 pkg/main.py
Traceback (most recent call last):
  File "pkg/main.py", line 2, in <module>
    print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'

Tuy nhiên, xa hơn trong biểu đồ thay đổi 2.5, chúng tôi thấy điều này (nhấn mạnh thêm):

Trong Python 2.5, bạn có thể chuyển importhành vi của thành nhập tuyệt đối bằng cách sử dụng một from __future__ import absolute_importchỉ thị. Hành vi nhập tuyệt đối này sẽ trở thành mặc định trong phiên bản tương lai (có thể là Python 2.7). Khi nhập tuyệt đối là mặc định, import stringsẽ luôn tìm thấy phiên bản của thư viện chuẩn.

Do đó pkg/main2.py, tôi đã tạo , giống hệt main.pynhưng với chỉ thị nhập bổ sung trong tương lai. Bây giờ nó trông như thế này:

from __future__ import absolute_import
import string
print string.ascii_uppercase

Tuy nhiên, chạy điều này với Python 2.5 ... không thành công với AttributeError:

$ python2.5 pkg/main2.py
Traceback (most recent call last):
  File "pkg/main2.py", line 3, in <module>
    print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'

Điều này hoàn toàn mâu thuẫn với tuyên bố rằng import stringsẽ luôn tìm thấy phiên bản std-lib với tính năng nhập tuyệt đối được bật. Hơn nữa, bất chấp cảnh báo rằng nhập tuyệt đối được lên lịch để trở thành hành vi "mặc định mới", tôi đã gặp phải vấn đề tương tự khi sử dụng cả Python 2.7, có hoặc không có lệnh __future__:

$ python2.7 pkg/main.py
Traceback (most recent call last):
  File "pkg/main.py", line 2, in <module>
    print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'

$ python2.7 pkg/main2.py
Traceback (most recent call last):
  File "pkg/main2.py", line 3, in <module>
    print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'

cũng như Python 3.5, có hoặc không (giả sử printcâu lệnh được thay đổi trong cả hai tệp):

$ python3.5 pkg/main.py
Traceback (most recent call last):
  File "pkg/main.py", line 2, in <module>
    print(string.ascii_uppercase)
AttributeError: module 'string' has no attribute 'ascii_uppercase'

$ python3.5 pkg/main2.py
Traceback (most recent call last):
  File "pkg/main2.py", line 3, in <module>
    print(string.ascii_uppercase)
AttributeError: module 'string' has no attribute 'ascii_uppercase'

Tôi đã thử nghiệm các biến thể khác của điều này. Thay vì string.py, tôi đã tạo ra một module rỗng - một thư mục có tên stringchứa duy nhất một sản phẩm nào __init__.py- và thay vì phát hành nhập khẩu từ main.py, tôi có cd'd pkgvà chạy hàng nhập khẩu trực tiếp từ REPL. Cả hai biến thể này (hoặc kết hợp chúng) đều không thay đổi kết quả ở trên. Tôi không thể dung hòa điều này với những gì tôi đã đọc về __future__chỉ thị và nhập khẩu tuyệt đối.

Đối với tôi, có vẻ như điều này có thể dễ dàng giải thích bằng cách sau (đây là từ tài liệu Python 2 nhưng câu lệnh này vẫn không thay đổi trong các tài liệu tương tự cho Python 3):

sys.path

(...)

Khi được khởi tạo khi khởi động chương trình, mục đầu tiên của danh sách này path[0], là thư mục chứa tập lệnh được sử dụng để gọi trình thông dịch Python. Nếu thư mục tập lệnh không có sẵn (ví dụ: nếu trình thông dịch được gọi tương tác hoặc nếu tập lệnh được đọc từ đầu vào chuẩn), path[0]là chuỗi trống, sẽ hướng Python đến tìm kiếm các mô-đun trong thư mục hiện tại trước tiên.

Vậy tôi đang thiếu gì? Tại sao __future__tuyên bố dường như không thực hiện những gì nó nói, và cách giải quyết mâu thuẫn này giữa hai phần tài liệu này, cũng như giữa hành vi được mô tả và thực tế là gì?

2 answers

104
user2357112 supports Monica 2015-11-17 10:35.

Bảng thay đổi được viết một cách cẩu thả. from __future__ import absolute_importkhông quan tâm đến việc một cái gì đó có phải là một phần của thư viện tiêu chuẩn hay import stringkhông và sẽ không phải lúc nào cũng cung cấp cho bạn mô-đun thư viện tiêu chuẩn khi bật nhập tuyệt đối.

from __future__ import absolute_importcó nghĩa là nếu bạn import string, Python sẽ luôn tìm kiếm một stringmô-đun cấp cao nhất , thay vì current_package.string. Tuy nhiên, nó không ảnh hưởng đến logic mà Python sử dụng để quyết định tệp là stringmô-đun. Khi bạn làm

python pkg/script.py

pkg/script.pykhông giống như một phần của gói đối với Python. Theo các quy trình thông thường, pkgthư mục được thêm vào đường dẫn và tất cả .pycác tệp trong pkgthư mục trông giống như các mô-đun cấp cao nhất. không import stringtìm thấy pkg/string.pybởi vì nó đang thực hiện một quá trình nhập tương đối, mà bởi vì nó pkg/string.pydường như là mô-đun cấp cao nhất string. Thực tế là đây không phải là stringmô-đun thư viện tiêu chuẩn không xuất hiện.

Để chạy tệp như một phần của pkggói, bạn có thể làm

python -m pkg.script

Trong trường hợp này, pkgthư mục sẽ không được thêm vào đường dẫn. Tuy nhiên, thư mục hiện tại sẽ được thêm vào đường dẫn.

Bạn cũng có thể thêm một số bản soạn sẵn pkg/script.pyđể làm cho Python coi nó như một phần của pkggói ngay cả khi chạy dưới dạng tệp:

if __name__ == '__main__' and __package__ is None:
    __package__ = 'pkg'

Tuy nhiên, điều này sẽ không ảnh hưởng sys.path. Bạn sẽ cần một số xử lý bổ sung để xóa pkgthư mục khỏi đường dẫn và nếu pkgthư mục mẹ của không có trên đường dẫn, bạn cũng cần phải gắn nó vào đường dẫn.

45
Bakuriu 2015-11-17 10:34.

Sự khác biệt giữa nhập tuyệt đối và nhập tương đối chỉ phát huy tác dụng khi bạn nhập một mô-đun từ một gói và mô-đun đó nhập một mô-đun con khác từ gói đó. Thấy sự khác biệt:

$ mkdir pkg
$ touch pkg/__init__.py
$ touch pkg/string.py
$ echo 'import string;print(string.ascii_uppercase)' > pkg/main1.py
$ python2
Python 2.7.9 (default, Dec 13 2014, 18:02:08) [GCC] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkg.main1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "pkg/main1.py", line 1, in <module>
    import string;print(string.ascii_uppercase)
AttributeError: 'module' object has no attribute 'ascii_uppercase'
>>> 
$ echo 'from __future__ import absolute_import;import string;print(string.ascii_uppercase)' > pkg/main2.py
$ python2
Python 2.7.9 (default, Dec 13 2014, 18:02:08) [GCC] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkg.main2
ABCDEFGHIJKLMNOPQRSTUVWXYZ
>>> 

Đặc biệt:

$ python2 pkg/main2.py
Traceback (most recent call last):
  File "pkg/main2.py", line 1, in <module>
    from __future__ import absolute_import;import string;print(string.ascii_uppercase)
AttributeError: 'module' object has no attribute 'ascii_uppercase'
$ python2
Python 2.7.9 (default, Dec 13 2014, 18:02:08) [GCC] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkg.main2
ABCDEFGHIJKLMNOPQRSTUVWXYZ
>>> 
$ python2 -m pkg.main2
ABCDEFGHIJKLMNOPQRSTUVWXYZ

Lưu ý rằng python2 pkg/main2.pycó một hành vi khác sau đó khởi chạy python2và sau đó nhập pkg.main2(tương đương với việc sử dụng công -mtắc).

Nếu bạn muốn chạy một mô-đun con của một gói, hãy luôn sử dụng công -mtắc để ngăn trình thông dịch chuỗi sys.pathdanh sách và xử lý chính xác ngữ nghĩa của mô-đun con.

Ngoài ra, tôi thích sử dụng nhập tương đối rõ ràng cho các mô-đun con của gói vì chúng cung cấp nhiều ngữ nghĩa hơn và thông báo lỗi tốt hơn trong trường hợp không thành công.

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Các luật sư của Trump muốn vụ kiện Stormy Daniels được giải quyết trước mắt công chúng

Các luật sư của Trump muốn vụ kiện Stormy Daniels được giải quyết trước mắt công chúng

Ảnh: Getty Nếu có vẻ như câu chuyện Stormy Daniels-Donald Trump là một trò chơi bất tận giữa các luật sư (một số người trong số họ rất ngu ngốc), đó là bởi vì nó là. Vào thứ Hai, các luật sư đại diện cho luật sư của Trump, Michael Cohen và Trump đã thực hiện vở kịch mới nhất của họ: một đề nghị để vụ việc được quyết định bởi một trọng tài riêng.

Colin Trevorrow sẽ trở lại để chỉ đạo phần ba của phim thế giới kỷ Jura

Colin Trevorrow sẽ trở lại để chỉ đạo phần ba của phim thế giới kỷ Jura

Chris Pratt và Colin Trevorrow trên phim trường Jurassic World. Người đàn ông đầu tiên mạo hiểm vào Thế giới kỷ Jura sẽ trở lại đó cho phần cuối của bộ ba.

Bạn sẽ phân biệt chủng tộc như thế nào nếu người da đen thực sự có thể phân biệt chủng tộc?

Bạn sẽ phân biệt chủng tộc như thế nào nếu người da đen thực sự có thể phân biệt chủng tộc?

Một trong những điều thất vọng lớn nhất trong cuộc đời tôi - có lẽ thực sự là thất vọng lớn nhất - là người da đen ở Mỹ không có khả năng phân biệt chủng tộc. Chúng ta có thể cố gắng hết sức và ghét nhất có thể, nhưng do cách thức hoạt động của chủ nghĩa phân biệt chủng tộc, chúng ta sẽ không bao giờ có thể sử dụng tình trạng được săn đón là “phân biệt chủng tộc.

Bạn không cần phải xả những củ khoai tây nghiền này ngay lập tức

Bạn không cần phải xả những củ khoai tây nghiền này ngay lập tức

Một trong những thứ yêu thích của tôi để nấu trong Instant Pot (hoặc bất kỳ nồi áp suất nào) là các loại rau củ, nếu không sẽ mất nhiều thời gian hơn. Khoai tây chắc chắn thuộc loại này, đặc biệt là vì bạn có thể làm khoai tây nghiền hoàn toàn như kem hoàn toàn trong Nồi ăn liền mà không cần xả nước.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Đường băng hạ cánh

Đường băng hạ cánh

Cuối hè đầu thu là mùa hoài niệm. Những chiếc đèn đường chiếu ánh sáng của chúng qua những con đường đẫm mưa, và những chiếc lá dưới chân - màu đỏ cam tắt trong bóng chạng vạng - là lời nhắc nhở về những ngày đã qua.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Language