嗨我有类似下面的东西.基本上我需要从定义中的实例方法使用的装饰器访问实例方法的类.
def decorator(view):
# do something that requires view's class
print view.im_class
return view
class ModelA(object):
@decorator
def a_method(self):
# do some stuff
pass
Run Code Online (Sandbox Code Playgroud)
代码原样给出
AttributeError: 'function' object has no attribute 'im_class'
我发现类似的问题/答案 - Python装饰器让函数忘记它属于一个类和Python装饰器中的Get类 - 但这些依赖于一种解决方法,它通过抢夺第一个参数在运行时抓取实例.在我的情况下,我将基于从其类中收集的信息调用该方法,因此我不能等待来电.
谢谢.
class A(object):
def get_class(self):
return self.__class__
class B(A):
def __init__(self):
A.__init__(self)
b = B()
print b.get_class()
Run Code Online (Sandbox Code Playgroud)
此代码将打印出来<class '__main__.B'>
.
如何获取定义方法的类名(即A
)?
假设我想为类中定义的方法创建装饰器.我希望装饰器在被调用时能够在定义方法的类上设置属性(以便将其注册到用于特定目的的方法列表中).
在Python 2中,该im_class
方法很好地完成了这个:
def decorator(method):
cls = method.im_class
cls.foo = 'bar'
return method
Run Code Online (Sandbox Code Playgroud)
但是,在Python 3中,似乎不存在这样的属性(或替代它).我想这个想法是你可以调用type(method.__self__)
来获取类,但是这对于未绑定的方法不起作用,因为__self__ == None
在那种情况下.
注意:这个问题实际上与我的情况有点无关,因为我选择在方法本身上设置属性,然后让实例扫描其所有方法,在适当的时间查找该属性.我(目前)也在使用Python 2.6.但是,我很好奇是否有替换版本2的功能,如果没有,那么完全删除它的理由是什么.
编辑:我刚发现这个问题.这使得看起来最好的解决方案就是像我一样避免它.我仍然想知道为什么它被删除了.
__qualname__
python中有什么,它有什么用?
为什么我需要使用它__name__
?
我阅读了文档,但它们并没有帮助我清楚地了解它的用处。
我已阅读获取 Python 类的完全限定名称 (Python 3.3+)。
这个问题问的是“如何获得一个合格的名字”,它假定人们知道“合格的名字”的含义。显然,该问题的答案是使用__qualname__
属性。
我的问题是什么 __qualname__
,为什么我应该在__name__
.
给出x = C.f
之后:
class C:
def f(self):
pass
Run Code Online (Sandbox Code Playgroud)
我会打电话给谁x
回来C
?
我能做的最好的是exec
解析部分x.__qualname__
,这是丑陋的:
exec('d = ' + ".".join(x.__qualname__.split('.')[:-1]))
Run Code Online (Sandbox Code Playgroud)
对于一个用例,想象一下我想要一个装饰器来添加super
对它应用的任何方法的调用.那个只给出函数对象的装饰器怎么能把类带到super
(???
下面)?
def ensure_finished(iterator):
try:
next(iterator)
except StopIteration:
return
else:
raise RuntimeError
def derived_generator(method):
def new_method(self, *args, **kwargs):
x = method(self, *args, **kwargs)
y = getattr(super(???, self), method.__name__)\
(*args, **kwargs)
for a, b in zip(x, y):
assert a is None and b is None
yield
ensure_finished(x)
ensure_finished(y)
return new_method
Run Code Online (Sandbox Code Playgroud)