gpt4 book ai didi

python - 方法的文本引用

转载 作者:行者123 更新时间:2023-12-01 05:49:23 27 4
gpt4 key购买 nike

假设我有以下内容:

def func():
print 'this is a function and not a method!!!'

class Test:
def TestFunc(self):
print 'this is Test::TestFunc method'

我有以下函数(取自 https://bitbucket.org/agronholm/apscheduler/src/d2f00d9ac019/apscheduler/util.py ):

def get_callable_name(func):
"""
Returns the best available display name for the given function/callable.
"""
f_self = getattr(func, '__self__', None) or getattr(func, 'im_self', None)
if f_self and hasattr(func, '__name__'):
if isinstance(f_self, type):
# class method
clsname = getattr(f_self, '__qualname__', None) or f_self.__name__
return '%s.%s' % (clsname, func.__name__)
# bound method
return '%s.%s' % (f_self.__class__.__name__, func.__name__)
if hasattr(func, '__call__'):
if hasattr(func, '__name__'):
# function, unbound method or a class with a __call__ method
return func.__name__
# instance of a class with a __call__ method
return func.__class__.__name__
raise TypeError('Unable to determine a name for %s -- '
'maybe it is not a callable?' % repr(func))


def obj_to_ref(obj):
"""
Returns the path to the given object.
"""
ref = '%s:%s' % (obj.__module__, get_callable_name(obj))
try:
obj2 = ref_to_obj(ref)
if obj != obj2:
raise ValueError
except Exception:
raise ValueError('Cannot determine the reference to %s' % repr(obj))
return ref


def ref_to_obj(ref):
"""
Returns the object pointed to by ``ref``.
"""
if not isinstance(ref, basestring):
raise TypeError('References must be strings')
if not ':' in ref:
raise ValueError('Invalid reference')
modulename, rest = ref.split(':', 1)
try:
obj = __import__(modulename)
except ImportError:
raise LookupError('Error resolving reference %s: '
'could not import module' % ref)
try:
for name in modulename.split('.')[1:] + rest.split('.'):
obj = getattr(obj, name)
return obj
except Exception:
raise LookupError('Error resolving reference %s: '
'error looking up object' % ref)

上述函数 - obj_to_ref 返回给定函数对象的文本引用,ref_to_obj 返回给定文本引用的对象。例如,让我们尝试一下 func 函数。

>>> 
>>> func
<function func at 0xb7704924>
>>>
>>> obj_to_ref(func)
'__main__:func'
>>>
>>> ref_to_obj('__main__:func')
<function func at 0xb7704924>
>>>

func 函数工作正常。但是,当尝试在 Test 类的实例上使用这些函数时,它无法获取文本引用。

>>> 
>>> t = Test()
>>>
>>> t
<__main__.Test instance at 0xb771b28c>
>>>
>>> t.TestFunc
<bound method Test.TestFunc of <__main__.Test instance at 0xb771b28c>>
>>>
>>>
>>> obj_to_ref(t.TestFunc)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 11, in obj_to_ref
ValueError: Cannot determine the reference to <bound method Test.TestFunc of <__main__.Test instance at 0xb771b28c>>
>>>
>>>

给定输入t.TestFuncobj_to_ref函数将__main__:Test.TestFunc作为文本表示,但具有相同的文本不能用于生成对象。

问题:

Python 中有没有一种方法可以表示像这样的对象

>>> t.TestFunc
<bound method Test.TestFunc of <__main__.Test instance at 0xb771b28c>>
>>>

在字符串中并从字符串重建对象?

如果我们将地址0xb771b28c保存为字符串的一部分,并通过取消引用该地址来重新生成对象,是否可以?!

最佳答案

正如我在上面的评论中所说,问题出在 get_callable_name 中。 get_callable_name(t.TestFunc) 产生 'Test.TestFunc' 这显然是错误的。它应该是“t.TestFunc”。我添加了 variable_name_in_module 并在 get_callable_name 中使用了它,现在代码可以工作了。底部的检查返回True。然而,variable_name_in_module 非常hackish,我找不到一种干净利落的方法来做到这一点。

如果您只需要这个来处理小东西,那么这应该没问题,但请注意,variable_name_in_module 会在每次调用 get_callable_name 时进行 N 字典查找,其中 N 是模块中的变量数量。

代码如下:

def variable_name_in_module(module, var):
for name in dir(module):
if getattr(module, name) == var:
return name

def get_callable_name(func):
"""
Returns the best available display name for the given function/callable.
"""
f_self = getattr(func, '__self__', None) or getattr(func, 'im_self', None)
if f_self and hasattr(func, '__name__'):
if isinstance(f_self, type):
# class method
clsname = getattr(f_self, '__qualname__', None) or f_self.__name__
return '%s.%s' % (clsname, func.__name__)
# bound method
return '%s.%s' % (variable_name_in_module(__import__(f_self.__module__), f_self), func.__name__)
if hasattr(func, '__call__'):
if hasattr(func, '__name__'):
# function, unbound method or a class with a __call__ method
return func.__name__
# instance of a class with a __call__ method
return func.__class__.__name__
raise TypeError('Unable to determine a name for %s -- '
'maybe it is not a callable?' % repr(func))


def obj_to_ref(obj):
"""
Returns the path to the given object.
"""
ref = '%s:%s' % (obj.__module__, get_callable_name(obj))
try:
obj2 = ref_to_obj(ref)
if obj != obj2:
raise ValueError
except Exception:
raise ValueError('Cannot determine the reference to %s' % repr(obj))
return ref


def ref_to_obj(ref):
"""
Returns the object pointed to by ``ref``.
"""
if not isinstance(ref, basestring):
raise TypeError('References must be strings')
if not ':' in ref:
raise ValueError('Invalid reference')
modulename, rest = ref.split(':', 1)
try:
obj = __import__(modulename)
except ImportError:
raise LookupError('Error resolving reference %s: '
'could not import module' % ref)
try:
for name in modulename.split('.')[1:] + rest.split('.'):
obj = getattr(obj, name)
return obj
except Exception:
raise LookupError('Error resolving reference %s: '
'error looking up object' % ref)

class Test:
def TestFunc(self):
print "test"

t = Test()
print t.TestFunc == ref_to_obj(obj_to_ref(t.TestFunc))

编辑:PS:variable_name_in_module如果找不到任何东西,可能应该抛出异常,尽管我不知道这是如何发生的。

关于python - 方法的文本引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14968349/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com