admin管理员组文章数量:1432643
In JavaScript, specifically in node.js setting, one can spell module.exports = 13;
in module.js
, then x = import ("module.js");
elsewhere and have 13 assigned to x directly.
This saves some code when a module exports a single function, and I notice a lot of widely used packages (such as through2) make use of it.
Is there a way to do the same in Python? With some black magic, maybe?
I do have heard of a thing called loader that's, I guess, supposed to do some manipulations with a module before making it available. In particular, I think SaltStack makes use of something like that in salt.loader
, but the code is too hard for me to follow. I imagine we could write a function similar to this:
def loader(module):
m = __import__(module)
return m["__exports__"]
— Then define __exports__
somewhere in a module we want to import and enjoy functionality very similar to JavaScript's module.exports
mechanics. But unfortunately TypeError: 'module' object has no attribute '__getitem__'
prevents us from doing that.
In JavaScript, specifically in node.js setting, one can spell module.exports = 13;
in module.js
, then x = import ("module.js");
elsewhere and have 13 assigned to x directly.
This saves some code when a module exports a single function, and I notice a lot of widely used packages (such as through2) make use of it.
Is there a way to do the same in Python? With some black magic, maybe?
I do have heard of a thing called loader that's, I guess, supposed to do some manipulations with a module before making it available. In particular, I think SaltStack makes use of something like that in salt.loader
, but the code is too hard for me to follow. I imagine we could write a function similar to this:
def loader(module):
m = __import__(module)
return m["__exports__"]
— Then define __exports__
somewhere in a module we want to import and enjoy functionality very similar to JavaScript's module.exports
mechanics. But unfortunately TypeError: 'module' object has no attribute '__getitem__'
prevents us from doing that.
2 Answers
Reset to default 2Python has importing built in to the language at a more basic level than Javascript does, almost all use cases are covered by a simple import statement.
For your example, all it really boils down to is:
from module import exports as x
So, there's not need to look for code savings by changing module
.
The other part of the question is how, as a module author, would you restrict people to seeing only a single symbol.
Generally this is not required except to help users know what are public functions vs implementation details. Python has a few mon idioms for this:
- Any names that start with a leading underscore, such as
_helper
, are considered private. They can be accessed as normal, but the implication is you should not. - If a module level variable
__all__ = [...]
exists, only the strings it contains are considered public. The names must seperatedly be declared in the module.
As well as being documentation, both of these do affect one aspect of the module import:
from module import *
Using a star import is generally discouraged, but only public names will be brought in to the local namespace.
After some thinking I understood that, while we can't say m["__exports__"]
due to module object's class not having __getitem__
method, we can still access some of the module's elements with "dot" notation: m.__exports__
works.
Another way: screen all module level names off with an underscore and assign the object to be exported to a variable named after the module, then from module import *
.
loader.py:
def loader(module):
m = __import__(module)
return m.__exports__
exports.py:
def _f():
return 13
_a = 31
exports = {"p6": _f, "p8": _a}
__exports__ = exports
Python 2.7:
>>> import loader
>>> e = loader.load ("exports")
>>> e
{'p8': 31, 'p6': <function _f at 0x7fb79d494cf8>}
>>> from exports import *
>>> exports
{'p8': 31, 'p6': <function _f at 0x7fb79d494cf8>}
Python 3:
>>> import loader
>>> e = loader.load ("exports")
>>> e
{'p6': <function _f at 0x7f88ae229ae8>, 'p8': 31}
>>> from exports import *
>>> exports
{'p6': <function _f at 0x7f88ae229ae8>, 'p8': 31}
In the first way proposed, I unfortunately cannot use __all__
in loader.load
to filter only listed names from a module being loaded since __getitem__
is not defined for module object.
In the second way proposed I don't get so much control (in that a malicious module can export arbitrary names and manipulate my namespace) and flexibility (in that I cannot assign the module's exported object to arbitrary name anywhere in my code).
So, there is still a bit left to be desired here.
本文标签: javascriptIn pythonquotexportquot a customtailored object from a moduleStack Overflow
版权声明:本文标题:javascript - In python, "export" a custom-tailored object from a module - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745503918a2661157.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论