def images_custom_list(args, producer_data):
tenant, token, url = producer_data
url = url.replace(".images", ".servers")
url = url + '/' + 'detail'
output = do_request(url, token)
output = output[0].json()["images"]
custom_images_list = [custom_images for custom_images in output
if custom_images["metadata"].get('user_id', None)]
temp_image_list = []
for image in custom_images_list:
image_temp = ( { "status": image["status"],
"links": image["links"][0]["href"],
"id": image["id"], "name": image["name"]} )
temp_image_list.append(image_temp)
print json.dumps(temp_image_list, indent=2)
def image_list_detail(args, producer_data):
tenant, token, url = producer_data
url = url.replace(".images", ".servers")
uuid = args['uuid']
url = url + "/" + uuid
output = do_request(url, token)
print output[0]
我试图通过利用Python的功能装饰使代码更高效,更干净。由于这两个函数共享相同的前两行,我怎么能用这两行创建一个函数修饰器并将这两个函数装饰好呢?
答案 0 :(得分:2)
这是一种解决方法:
from functools import wraps
def fix_url(function):
@wraps(function)
def wrapper(*args, **kwarg):
kwarg['url'] = kwarg['url'].replace(".images", ".servers")
return function(*args, **kwarg)
return wrapper
@fix_url
def images_custom_list(args, tenant=None, token=None, url=None):
url = url + '/' + 'detail'
output = do_request(url, token)
output = output[0].json()["images"]
custom_images_list = [custom_images for custom_images in output
if custom_images["metadata"].get('user_id', None)]
temp_image_list = []
for image in custom_images_list:
image_temp = ( { "status": image["status"],
"links": image["links"][0]["href"],
"id": image["id"], "name": image["name"]} )
temp_image_list.append(image_temp)
print json.dumps(temp_image_list, indent=2)
@fix_url
def image_list_detail(args, tenant=None, token=None, url=None):
uuid = args['uuid']
url = url + "/" + uuid
output = do_request(url, token)
print output[0]
遗憾的是,您可能会注意到您需要摆脱producer_data
,但是将它拆分为多个参数,因为您无法分解代码的这一部分,因为您无论如何都需要再次拆分它在每个功能中。我选择使用关键字参数(通过将默认值设置为None
),但您也可以使用位置参数,即调用。
N.B。:它基本上是基于@ joel-cornett的例子(我不会使用@wraps
,只是普通的旧双功能装饰器),我只是专门用它。 (我认为他不值得-1)
请至少+1
他的回答或接受。
但我认为更简单的方法是:
def fix_url(producer_data):
return (producer_data[0], producer_data[1], producer_data[2].replace(".images", ".servers"))
def images_custom_list(args, producer_data):
tenant, token, url = fix_url(producer_data)
# stuff ...
def image_list_detail(args, producer_data):
tenant, token, url = fix_url(producer_data)
# stuff ...
使用更简单的语法(没有装饰器),只进行一次函数调用。
答案 1 :(得分:1)
像这样:
from functools import wraps
def my_timesaving_decorator(function):
@wraps(function)
def wrapper(*args, **kwargs):
execute_code_common_to_multiple_function()
#Now, call the "unique" code
#Make sure that if you modified the function args,
#you pass the modified args here, not the original ones.
return function(*args, **kwargs)
return wrapper