Khi sử dụng __import__
với tên chấm chấm, chẳng hạn như: somepackage.somemodule
, mô-đun được trả lại không phải là somemodule
, bất kỳ thứ gì được trả về có vẻ hầu như trống! những gì đang xảy ra ở đây?__import__ của Python không hoạt động như mong đợi
Trả lời
Từ các tài liệu python trên __import__
:
__import__(name[, globals[, locals[, fromlist[, level]]]])
...
Khi biến tên có dạng package.module, thông thường, các gói cấp cao nhất (các tên lên đến dấu chấm đầu tiên) được trả lại, không phải là mô-đun được đặt tên theo tên. Tuy nhiên, khi một đối số không được để trống , mô-đun được đặt tên theo tên được trả về. Điều này được thực hiện để tương thích với mã bytecode được tạo cho các loại báo cáo nhập khác nhau; khi sử dụng "import spam.ham.eggs", thư rác gói cấp cao nhất phải được đặt trong không gian tên nhập, nhưng khi sử dụng "từ spam.ham nhập trứng", thì phải sử dụng gói phụ spam.ham.ham.ham tới số tìm biến số trứng. Để giải quyết sự cố này, hãy sử dụng getattr() để trích xuất các thành phần mong muốn mong muốn. Ví dụ, bạn có thể xác định helper sau:
def my_import(name): mod = __import__(name) components = name.split('.') for comp in components[1:]: mod = getattr(mod, comp) return mod
Để diễn giải:
Khi bạn yêu cầu somepackage.somemodule
, __import__
lợi nhuận somepackage.__init__.py
, mà thường là rỗng.
Nó sẽ trở lại somemodule
nếu bạn cung cấp fromlist
(một danh sách các tên biến bên somemodule
bạn muốn, mà không thực sự trả lại)
Bạn cũng có thể, như tôi đã làm, sử dụng chức năng họ đề nghị.
Lưu ý: Tôi đã hỏi câu hỏi này có ý định hoàn toàn để tự trả lời. Có một lỗi lớn trong mã của tôi, và đã chẩn đoán sai nó, nó đã cho tôi một thời gian dài để tìm ra nó, vì vậy tôi figured tôi sẽ giúp cộng đồng SO ra và đăng các gotcha tôi chạy vào đây.
Có một cái gì đó mà làm việc như bạn muốn nó: twisted.python.reflect.namedAny
:
>>> from twisted.python.reflect import namedAny
>>> namedAny("operator.eq")
<built-in function eq>
>>> namedAny("pysqlite2.dbapi2.connect")
<built-in function connect>
>>> namedAny("os")
<module 'os' from '/usr/lib/python2.5/os.pyc'>
python 2.7 có importlib, đường dẫn chấm giải quyết như mong đợi
import importlib
foo = importlib.import_module('a.dotted.path')
instance = foo.SomeClass()
Ngoài ra còn có một gói python 2.6 giúp backports chức năng này. https://pypi.python.org/pypi/importlib/ – melinath
Đối với python 2.6, tôi đã viết đoạn này:
def import_and_get_mod(str, parent_mod=None):
"""Attempts to import the supplied string as a module.
Returns the module that was imported."""
mods = str.split('.')
child_mod_str = '.'.join(mods[1:])
if parent_mod is None:
if len(mods) > 1:
#First time this function is called; import the module
#__import__() will only return the top level module
return import_and_get_mod(child_mod_str, __import__(str))
else:
return __import__(str)
else:
mod = getattr(parent_mod, mods[0])
if len(mods) > 1:
#We're not yet at the intended module; drill down
return import_and_get_mod(child_mod_str, mod)
else:
return mod
Có giải pháp đơn giản hơn, như được giải thích trong tài liệu:
Nếu bạn chỉ muốn nhập mô-đun (có khả năng trong một gói) theo tên, bạn có thể gọi __import __() và sau đó tìm kiếm trong sys.module:
>>> import sys
>>> name = 'foo.bar.baz'
>>> __import__(name)
<module 'foo' from ...>
>>> baz = sys.modules[name]
>>> baz
<module 'foo.bar.baz' from ...>
Con đường tôi đã làm là
foo = __import__('foo', globals(), locals(), ["bar"], -1)
foobar = eval("foo.bar")
sau đó tôi có thể truy cập bất kỳ nội dung từ bằng cách
foobar.functionName()
Tại sao không chỉ, 'foo.bar' vào thời điểm đó? –
- 1. os.path.isfile không hoạt động như mong đợi
- 2. Tập hợp Python(). Issubset() không hoạt động như mong đợi
- 3. chrome.runtime.sendMessage không hoạt động như mong đợi
- 4. TagBuilder.MergeAttributes không hoạt động như mong đợi
- 5. kendo.ui.progress không hoạt động như mong đợi
- 6. SmartGit không hoạt động như mong đợi
- 7. Time.use_zone không hoạt động như mong đợi
- 8. golang TCPConn.SetWriteDeadline dường như không hoạt động như mong đợi
- 9. Twitter Lưới khởi động không hoạt động như mong đợi
- 10. libgdx setOrigin và setPosition không hoạt động như mong đợi?
- 11. Nhóm Django không hoạt động như mong đợi
- 12. Backbone JS Routing không hoạt động như tôi mong đợi
- 13. jQuery fadeOut/fadeTrong không hoạt động như mong đợi?
- 14. jQuery $ (cửa sổ) .load không hoạt động như mong đợi
- 15. Mã hóa JBOSS 7 không hoạt động như mong đợi
- 16. Toán tử ternary PHP không hoạt động như mong đợi
- 17. TextView android: ellipsize = "marquee" không hoạt động như mong đợi
- 18. Chia sẻ tệp không hoạt động như mong đợi
- 19. Zend headScript() và appendFile không hoạt động như mong đợi
- 20. matplotlib axes.set_aspect ('bằng') không hoạt động như mong đợi
- 21. Lớp POCO trong EF không hoạt động như mong đợi
- 22. webdriver implicitWait không hoạt động như mong đợi
- 23. Thẻ dự kiến JUnit không hoạt động như mong đợi
- 24. PHP is_int không hoạt động như mong đợi
- 25. android: layout_gravity không hoạt động như mong đợi
- 26. AngularJs $ scope. $ Áp dụng không hoạt động như mong đợi
- 27. java.util.BitSet - set() không hoạt động như mong đợi
- 28. gdb bước không hoạt động như mong đợi
- 29. Rx Thử lại() không hoạt động như mong đợi
- 30. Giao dịch SQLite không hoạt động như mong đợi
Đó là rất hữu ích, tuy nhiên tôi không thực sự có bất cứ nhu cầu khác cho xoắn trong chương trình của tôi. Mặc dù, với tư cách là người sáng lập (!), Bạn có thể hiểu biết nhiều về khả năng hơn tôi (không bao giờ sử dụng nó). – dwestbrook