我如何编写一个装饰器和 return 一个经过身份验证的对象
How do I write a decorator and return an authenticated object
我正在编写自动化脚本,用于通过 jira python 库向 Jira 添加一些错误。
我在一个文件中有我的用户名和密码,我想确保每次调用一个函数(adds/modifies 一个错误)都经过验证。
基本上我想写一个装饰器。但是这个装饰器将 return 一个 jira 对象,每个函数都应该使用它。下面是我要写的函数。
def return_authed_jira():
options = {'server': 'https://jira.xxxxyyzzz.com'}
authed_jira = JIRA(options, basic_auth=('my_uname', my_passwd))
return authed_jira
有没有一种方法可以使用装饰器来做到这一点。再一次,我知道我可以在不使用装饰器的情况下以不同的方式来做,但我想用装饰器来做到这一点。
我试过自己写,但是我看到的大多数例子都没有return一个对象。
这是我试过的。
def authenticate(func):
def authenticate_and_call(*args, **kwargs):
options = {'server': 'https://jira.xxxxxxx.com', 'verify': False}
jira = JIRA(options)
if not jira.current_user() == 'uname':
options = {'server': 'https://jira.xxxxxx.com', 'verify': False}
jira = JIRA(options, basic_auth=('uname', passwd))
args.append(jira)
return func(*args, **kwargs)
return authenticate_and_call
我在这里尝试附加 jira 对象,但没有成功。
这是我想要的。将 jira 对象添加到 args 并不能使函数访问变得容易。这类似于登录装饰器,如果您尝试访问需要用户登录的页面,您可以将装饰器添加到为该页面提供服务的函数中。
@authenticate
def create_new_jira_bug(jira_fields):
new_issue = jira.create_issue(jira_fields)
print new_issue.id
下面是Blckknght
回答问题并修改后的新代码
def authenticate(func):
def authenticate_and_call(*args, **kwargs):
options = {'server': 'https://jira.xyz.com', 'verify': False}
jira = JIRA(options)
if not jira.current_user() == 'uname':
options = {'server': 'https://jira.xyz.com', 'verify': False}
jira = JIRA(options, basic_auth=(uname, password))
return func(*args, jira=jira, **kwargs)
return authenticate_and_call
@authenticate
def list_projects():
my_issue = jira.issue('MYKEY-1289')
print (my_issue.raw.get('fields'))
list_projects()
下面是我没有将 jira 添加到 list_projects 函数时出现的错误
Traceback (most recent call last):
File "C:/testjira.py", line 44, in <module>
list_projects()
File "C:testjira.py", line 33, in authenticate_and_call
return func(*args, jira=jira, **kwargs)
TypeError: list_projects() takes no arguments (1 given)
我的问题是我必须将 jira 对象传递给调用装饰器之前的函数,否则会出现此错误。有其他选择吗?它适用于以下代码。我正在尝试解释为什么在定义函数时必须传递对象,而在调用函数时不必传递该对象。
@authenticate
def list_projects(jira):
my_issue = jira.issue('MYKEY-1289')
print (my_issue.raw.get('fields'))
list_projects()
你不能 append
到 args
因为它是元组,而不是列表。要添加一个值,您需要创建一个新的元组,并将值连接起来:
args = args + (jira,)
注意(jira,)
末尾的逗号,有必要将其设为一元组,而不是简单的括号表达式。
您还需要设置要修饰的函数以期待 jira
参数:
@authenticate
def create_new_jira_bug(jira_fields, jira): # expects jira arg from decorator
new_issue = jira.create_issue(jira_fields)
print new_issue.id
请注意,我没有为 jira
提供默认值。您当前的代码仅在某些时候将 jira
参数添加到 args
,如果 jira
是必需的参数,这将不起作用。始终从装饰器传递它可能更有意义。
向装饰器进行的调用添加关键字参数可能更自然,而不是额外的位置参数。这将要求您正在装饰的所有函数对装饰器传入的 jira
对象使用相同的名称,但不会干扰它们对其他关键字参数的处理。将位置参数添加到现有参数的末尾(如您当前所做的那样)可能会中断使用关键字参数的调用。下面是 keyword-using 装饰器的样子:
def authenticate(func):
def authenticate_and_call(*args, **kwargs):
options = {'server': 'https://jira.xxxxxxx.com', 'verify': False}
jira = JIRA(options)
if not jira.current_user() == 'uname':
jira = JIRA(options, basic_auth=('uname', passwd))
return func(*args, jira=jira, **kwargs)
return authenticate_and_call
这将与上面的函数一起使用,但不会干扰像这样的调用:
create_new_jira_bug(jira_fields={"foo": "bar"})
我正在编写自动化脚本,用于通过 jira python 库向 Jira 添加一些错误。
我在一个文件中有我的用户名和密码,我想确保每次调用一个函数(adds/modifies 一个错误)都经过验证。
基本上我想写一个装饰器。但是这个装饰器将 return 一个 jira 对象,每个函数都应该使用它。下面是我要写的函数。
def return_authed_jira():
options = {'server': 'https://jira.xxxxyyzzz.com'}
authed_jira = JIRA(options, basic_auth=('my_uname', my_passwd))
return authed_jira
有没有一种方法可以使用装饰器来做到这一点。再一次,我知道我可以在不使用装饰器的情况下以不同的方式来做,但我想用装饰器来做到这一点。
我试过自己写,但是我看到的大多数例子都没有return一个对象。
这是我试过的。
def authenticate(func):
def authenticate_and_call(*args, **kwargs):
options = {'server': 'https://jira.xxxxxxx.com', 'verify': False}
jira = JIRA(options)
if not jira.current_user() == 'uname':
options = {'server': 'https://jira.xxxxxx.com', 'verify': False}
jira = JIRA(options, basic_auth=('uname', passwd))
args.append(jira)
return func(*args, **kwargs)
return authenticate_and_call
我在这里尝试附加 jira 对象,但没有成功。
这是我想要的。将 jira 对象添加到 args 并不能使函数访问变得容易。这类似于登录装饰器,如果您尝试访问需要用户登录的页面,您可以将装饰器添加到为该页面提供服务的函数中。
@authenticate
def create_new_jira_bug(jira_fields):
new_issue = jira.create_issue(jira_fields)
print new_issue.id
下面是Blckknght
回答问题并修改后的新代码
def authenticate(func):
def authenticate_and_call(*args, **kwargs):
options = {'server': 'https://jira.xyz.com', 'verify': False}
jira = JIRA(options)
if not jira.current_user() == 'uname':
options = {'server': 'https://jira.xyz.com', 'verify': False}
jira = JIRA(options, basic_auth=(uname, password))
return func(*args, jira=jira, **kwargs)
return authenticate_and_call
@authenticate
def list_projects():
my_issue = jira.issue('MYKEY-1289')
print (my_issue.raw.get('fields'))
list_projects()
下面是我没有将 jira 添加到 list_projects 函数时出现的错误
Traceback (most recent call last):
File "C:/testjira.py", line 44, in <module>
list_projects()
File "C:testjira.py", line 33, in authenticate_and_call
return func(*args, jira=jira, **kwargs)
TypeError: list_projects() takes no arguments (1 given)
我的问题是我必须将 jira 对象传递给调用装饰器之前的函数,否则会出现此错误。有其他选择吗?它适用于以下代码。我正在尝试解释为什么在定义函数时必须传递对象,而在调用函数时不必传递该对象。
@authenticate
def list_projects(jira):
my_issue = jira.issue('MYKEY-1289')
print (my_issue.raw.get('fields'))
list_projects()
你不能 append
到 args
因为它是元组,而不是列表。要添加一个值,您需要创建一个新的元组,并将值连接起来:
args = args + (jira,)
注意(jira,)
末尾的逗号,有必要将其设为一元组,而不是简单的括号表达式。
您还需要设置要修饰的函数以期待 jira
参数:
@authenticate
def create_new_jira_bug(jira_fields, jira): # expects jira arg from decorator
new_issue = jira.create_issue(jira_fields)
print new_issue.id
请注意,我没有为 jira
提供默认值。您当前的代码仅在某些时候将 jira
参数添加到 args
,如果 jira
是必需的参数,这将不起作用。始终从装饰器传递它可能更有意义。
向装饰器进行的调用添加关键字参数可能更自然,而不是额外的位置参数。这将要求您正在装饰的所有函数对装饰器传入的 jira
对象使用相同的名称,但不会干扰它们对其他关键字参数的处理。将位置参数添加到现有参数的末尾(如您当前所做的那样)可能会中断使用关键字参数的调用。下面是 keyword-using 装饰器的样子:
def authenticate(func):
def authenticate_and_call(*args, **kwargs):
options = {'server': 'https://jira.xxxxxxx.com', 'verify': False}
jira = JIRA(options)
if not jira.current_user() == 'uname':
jira = JIRA(options, basic_auth=('uname', passwd))
return func(*args, jira=jira, **kwargs)
return authenticate_and_call
这将与上面的函数一起使用,但不会干扰像这样的调用:
create_new_jira_bug(jira_fields={"foo": "bar"})