我需要一个函数来返回调用该函数的模块的包的名称。获取模块的名称很简单:
import inspect
module_name = inspect.currentframe().f_back.f_globals['__name__']
剥离最后一部分以获得模块的包也很容易:
package_name = '.'.join(module_name.split('.')[:-1])
但是如果从包的__init__.py
调用该函数,则不应剥离该名称的最后部分。例如。如果从foo/bar/__init__.py
调用,则上例中的module_name
将设置为'foo.bar'
,这已经是包的名称。
如何从模块名称或模块对象中检查它是指包还是模块?
我找到的最好方法是获取模块对象的__file__
属性(如果存在),并检查它是否指向名称为__init__
加上扩展名的文件。但这对我来说似乎很脆弱。
答案 0 :(得分:1)
:
module.__package__
适用于我看过的几个,看起来是正确的。它可能不会给你你想要的东西:
import os.path
import httplib2
import xml.etree.ElementTree as etree
os.path.__package__
<blank... this is a builtin>
httplib2.__package__
'httplib2'
etree.__package__
'xml.etree'
你可以使用
function.__module__
同样,但是它给出了模块名称,而不是实际模块 - 不确定是否有更简单的方法来获取模块对象本身,而不是再次导入到本地变量。
etree.parse.__module__
'xml.etree.ElementTree'
os.path.split.__module__
'ntpath'
根据事物的实际位置,这似乎更正确,例如:
httplib2.Response.__module__
'httplib2'
httplib2.copy.copy.__module__
'copy'
httplib2.urlparse.ParseResult.__module__
'urlparse'
等
答案 1 :(得分:1)
这就是importlib.__import__()
所做的,它需要重新实现Python的大部分内置导入逻辑,并且需要找到一个模块的包以支持相对导入:
# __package__ is not guaranteed to be defined or could be set to None
# to represent that it's proper value is unknown
package = globals.get('__package__')
if package is None:
package = globals['__name__']
if '__path__' not in globals:
package = package.rpartition('.')[0]
module = _gcd_import(name, package, level)
因此似乎没有可靠的“直接”方式来获取模块的包。