Twisted 有 #2 作为 twisted/python/reflect.py 。您需要类似的东西来制作基于字符串的配置系统,例如 Django 的 urls.py 配置。
查看代码和版本控制日志,看看他们必须做些什么才能使其工作 - 失败!- 正确的方式。
您正在寻找的其他东西对 Python 环境施加了足够的限制,以至于没有通用解决方案之类的东西。
这是在某种程度上实现了您的#1的东西
>>> import pickle
>>> def identify(f):
... name = f.__name__
... module_name = pickle.whichmodule(f, name)
... return module_name + "." + name
...
>>> identify(math.cos)
'math.cos'
>>> from xml.sax.saxutils import handler
>>> identify(handler)
'__main__.xml.sax.handler'
>>>
你的#3 定义不足。如果我做
__builtin__.step = path.to.your.stap
那么搜索代码是否应该将其查找为“步骤”?
我能想到的最简单的实现只是搜索所有模块并查找正是您想要的顶级元素
>>> import sys
>>> def _find_paths(x):
... for module_name, module in sys.modules.items():
... if module is None:
... continue
... for (member_name, obj) in module.__dict__.items():
... if obj is x:
... yield module_name + "." + member_name
...
>>> def find_shortest_name_to_object(x):
... return min( (len(name), name) for name in _find_paths(x) )[1]
...
>>> find_shortest_name_to_object(handler)
'__builtin__._'
>>> 5
5
>>> find_shortest_name_to_object(handler)
'xml.sax.handler'
>>>
在这里你可以看到'handler'实际上是在前面表达式返回的_中,使它成为最短的名字。
如果你想要别的东西,比如递归搜索所有模块的所有成员,那么只需编写代码。但正如“_”示例所示,会有惊喜。另外,这并不稳定,因为导入另一个模块可能会使另一个对象路径可用且更短。
这就是为什么人们一遍又一遍地说你想要的东西实际上对任何东西都没有用,这就是为什么没有模块的原因。
至于你的#4,世界上任何通用包将如何满足这些命名需求?
无论如何,你写了
请不要试图向我展示这些东西的快速实现。它比看起来更复杂,有很多陷阱,任何快速-n-脏代码都可能在许多重要情况下失败。这类任务需要经过实战测试的代码。
因此,不要将我的示例视为解决方案,而是将其视为您所要求的示例毫无意义的示例。这是一个如此脆弱的解决方案空间,很少有人冒险(主要是出于好奇)有如此不同的担忧,以至于一次性定制解决方案是最好的选择。其中大多数的模块是没有意义的,如果它确实有意义,那么对模块作用的解释可能会比代码更长。
因此,您的问题的答案是“不,没有这样的模块”。
让您的问题更令人困惑的是 Python 的 C 实现已经定义了一个“对象地址”。id()的文档说:
CPython 实现细节:这是对象的地址。
您要查找的是对象的名称或路径。不是“Python 对象地址”。