python - 如何从内部装饰器类访问类的实例?
问题描述
我有一个类来处理对服务器的 API 调用。类中的某些方法需要用户登录。由于会话可能会用完,因此我需要一些功能,以便在会话超时后重新登录用户。我的想法是使用装饰器。如果我这样尝试
class Outer_Class():
class login_required():
def __init__(self, decorated_func):
self.decorated_func = decorated_func
def __call__(self, *args, **kwargs):
try:
response = self.decorated_func(*args, **kwargs)
except:
print('Session probably timed out. Logging in again ...')
args[0]._login()
response = self.decorated_func(*args, **kwargs)
return response
def __init__(self):
self.logged_in = False
self.url = 'something'
self._login()
def _login(self):
print(f'Logging in on {self.url}!')
self.logged_in = True
#this method requires the user to be logged in
@login_required
def do_something(self, param_1):
print('Doing something important with param_1')
if (): #..this fails
raise Exception()
我得到一个错误。AttributeError: 'str' object has no attribute '_login'
为什么我没有通过 *args 获得对 Outer_Class 实例的引用?还有另一种方法来获取对实例的引用吗?
找到这个答案How to get instance given a method of the instance? ,但 decorated_function 似乎没有引用它自己的实例。
当我在课堂外使用装饰器功能时,它工作正常。这解决了问题,但我想知道,如果有可能解决这种方式。
解决方案
问题在于将对象作为第一个隐藏参数传递的魔力仅适用于非静态方法。由于您的装饰器返回一个不是函数的自定义可调用对象,因此它永远不会接收在调用中丢失的调用对象。因此,当您尝试调用修饰函数时,您只需将其传递param_1
到self
. 你得到第一个异常do_something() missing 1 required positional argument: 'param_1'
,陷入困境except
并得到你的错误。
您仍然可以将装饰器绑定到类,但它必须是一个具有self
神奇作用的函数:
class Outer_Class():
def login_required(decorated_func):
def inner(self, *args, **kwargs):
print("decorated called")
try:
response = decorated_func(self, *args, **kwargs)
except:
print('Session probably timed out. Logging in again ...')
self._login()
response = decorated_func(self, *args, **kwargs)
return response
return inner
...
#this method requires the user to be logged in
@login_required
def do_something(self, param_1):
print('Doing something important with param_1', param_1)
if (False): #..this fails
raise Exception()
然后您可以成功执行以下操作:
>>> a = Outer_Class()
Logging in on something!
>>> a.do_something("foo")
decorated called
Doing something important with param_1
推荐阅读
- javascript - 为什么我的反向链表返回空值?
- python - 创建新的 pd 数据框列,该列提供基于日期和星期起始数据的日期
- python - 将字符串前缀添加到列
- node.js - 在节点 js 中检查 docker swarm 容器状态
- php - 已经有 MySQL WorkBench,所以在安装 XAMPP 时没有选择 MySQL,如何从 XAMPP 连接到 WorkBench
- arrays - 逆向工程和解释汇编代码
- apache-kafka - 在使用 Flink Stateful 函数时,是否有一种简单的方法来处理来自同一个 kafka 入口主题的多种消息类型
- python-3.x - 这个错误是什么以及如何摆脱它。TypeError:“NoneType”类型的参数不可迭代
- python - TabError:创建函数时缩进中制表符和空格的使用不一致
- javascript - 如何将嵌套表中的问题id与主表匹配