[英]How to call a function inside a class and with no parameters? Want solutions with no decorator
[英]How to call specific function based on parameters to decorator
免责声明:我显然是新来的装饰
在python中创建和装饰函数非常简单直接,这个出色的答案 (投票最多的人)给出了很好的介绍,并展示了如何嵌套装饰器。 好吧,这一切都很好。 但是我还没有弄清楚有多少(python)-web-frameworks(烧瓶,django等)可以调用,我只能猜测是基于传递给装饰器的 参数的装饰函数 。
一个示例(使用Flask,但在许多框架中类似)向您展示我的意思。
@application.route('/page/a_page')
def show_a_page():
return html_content
@application.route('/page/another_page')
def show_another_page():
return html_content
现在,如果我以某种方式向mysite.com/page/a_page
烧瓶发出请求,那么它应该调用show_a_page
, show_another_page
如果请求是到mysite.com/page/a_page
,则show_another_page
也是如此。
我想知道如何在自己的项目中实现类似的功能?
我想存在类似于使用dir(module_name)
提取有关每个函数的修饰(?)的信息吗 ?
除了包装函数外,装饰器没有理由不能做其他事情
>>> def print_stuff(stuff):
... def decorator(f):
... print stuff
... return f
... return decorator
...
>>> @print_stuff('Hello, world!')
... def my_func():
... pass
...
Hello, world!
在此示例中,我们在定义函数时仅打印出传递给装饰器的构造函数的参数。 注意,我们打印了“你好,世界!” 而不实际调用my_func
这是因为打印是在构造装饰器时发生的,而不是在装饰器本身中发生的。
发生的情况是application.route
本身不是装饰器。 而是,它是一个采用路由并产生装饰器的函数,该装饰器将应用于视图函数,并在该路由处注册视图函数。 在flask中,装饰器构造函数可以访问路由和视图函数,因此可以在该路由上将视图函数注册到应用程序对象上。 如果您有兴趣,可以在Github上查看Flask源代码:
装饰器对函数的作用取决于它。 它可以将其包装在另一个函数中,向其属性添加一些元信息,甚至将其存储在字典中。
这是一个如何将多个函数保存到字典中的示例,以后可以将其用于查找这些函数:
function_table = {}
def add_to_table(name):
def dec(func):
def inner_func(*args, **kwargs):
return func(*args, **kwargs)
function_table[name] = inner_func
return inner_func
return dec
@add_to_table("my_addition_function")
def myfunction(a, b):
return a + b
@add_to_table("my_subtraction_function")
def myfunction2(a, b):
return a - b
print myfunction(1, 3)
# 4
print function_table["my_addition_function"](1, 4)
# 5
print function_table["my_subtraction_function"](1, 4)
# -3
这是Flask正在做的一个非常简单的版本:根据正在使用的路径存储要调用的函数的表。
这是一个使用BeautifulSoup的粗略示例,它基于David Robinson的答案。 装饰器将传递给它的字符串用作与功能相对应的字典的键。 这是通过关键字参数传递到调用它的修饰函数的。
import os
import sys
# Import System libraries
from copy import deepcopy
# Import Custom libraries
from BeautifulSoup import BeautifulSoup, Tag
page_base_str = \
'''
<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
div {
width: 600px;
margin: 5em auto;
padding: 50px;
background-color: #fff;
border-radius: 1em;
}
a:link, a:visited {
color: #38488f;
text-decoration: none;
}
@media (max-width: 700px) {
body {
background-color: #fff;
}
div {
width: auto;
margin: 0 auto;
border-radius: 0;
padding: 1em;
}
}
</style>
</head>
<body>
<div>
<h1>Example Domain</h1>
<div id="body">
<p>This domain is established to be used for illustrative examples in documents. You may use this
domain in examples without prior coordination or asking for permission.</p>
<p><a href="http://www.iana.org/domains/example">More information...</a></p>
</div>
</div>
</body>
</html>
'''
page_base_tag = BeautifulSoup(page_base_str)
def default_gen(*args):
return page_base_tag.prettify()
def test_gen(**kwargs):
copy_tag = deepcopy(page_base_tag)
title_change_locations = \
[
lambda x: x.name == u"title",
lambda x: x.name == u"h1"
]
title = kwargs.get("title", "")
if(title):
for location in title_change_locations:
search_list = copy_tag.findAll(location)
if(not search_list):
continue
tag_handle = search_list[0]
tag_handle.clear()
tag_handle.insert(0, title)
body_change_locations = \
[
lambda x: x.name == "div" and set([(u"id", u"body")]) <= set(x.attrs)
]
body = kwargs.get("body", "")
if(body):
for location in body_change_locations:
search_list = copy_tag.findAll(location)
if(not search_list):
continue
tag_handle = search_list[0]
tag_handle.clear()
tag_handle.insert(0, body)
return copy_tag.prettify()
page_gens = \
{
"TEST" : test_gen
}
def page_gen(name = ""):
def dec(func):
def inner_func(**kwargs):
kwargs["PAGE_FUNC"] = page_gens.get(name, default_gen)
return func(**kwargs)
return inner_func
return dec
@page_gen("TEST")
def test_page_01(**kwargs):
content = kwargs["PAGE_FUNC"](title = "Page 01", body = "Page 01 body")
return content
@page_gen("TEST")
def test_page_02(**kwargs):
content = kwargs["PAGE_FUNC"](title = "Page 02", body = "Page 02 body")
return content
@page_gen()
def a_page(**kwargs):
content = kwargs["PAGE_FUNC"]()
return content
print test_page_01()
print test_page_02()
print a_page()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.