为简化起见,我指的是HTML代码,尽管有所不同。
我使用装饰器生成此类代码。
我必须通过缩进来格式化输出。 我认为我需要跟踪嵌套级别以适应缩进,但是我不知道是否以及如何跟踪嵌套级别。 例如(https://www.thecodeship.com/patterns/guide-to-python-function-decorators/)
def p_decorate(func):
def func_wrapper(name):
return "<p>{0}</p>".format(func(name))
return func_wrapper
def strong_decorate(func):
def func_wrapper(name):
return "<strong>{0}</strong>".format(func(name))
return func_wrapper
def div_decorate(func):
def func_wrapper(name):
return "<div>{0}</div>".format(func(name))
return func_wrapper
get_text = div_decorate(p_decorate(strong_decorate(get_text)))
@div_decorate
@p_decorate
@strong_decorate
def get_text(name):
return "lorem ipsum, {0} dolor sit amet".format(name)
print(get_text("John"))
# Outputs <div><p><strong>lorem ipsum, John dolor sit amet</strong></p></div>
我想使用通用算法获得
<div>
<p>
<strong>lorem ipsum, John dolor sit amet</strong>
</p>
</div>
有可能吗?以及如何?
我有一个代码,但是很长。
EDit:由于人们在这里询问了真实的示例,所以您拥有我旨在获得的输出
config vdom
edit <vdom>
config router static
edit <number>
set dst <ip> <netmask>
set gateway <ip>
set device <intf>
next
end
end
谢谢
答案 0 :(得分:1)
您可以使用递归来构建嵌套的列表列表以存储整体结构。由于您的装饰器遵循类似的{tag}_decorate
模式,因此可以使用带有__getattr__
的类来消除为每个所需的HTML标签创建单独的装饰器功能的需要。可以递归遍历返回的嵌套列表以生成所需的结构。 traverse
函数存储一个计数器以跟踪缩进:
class HTML:
def __getattr__(self, tag):
def outer(f):
def wrapper(name):
return [tag, f(name)]
return wrapper
return outer
def traverse(d, c = 0):
a, b = d
if not isinstance(b, list):
return f'{" "*c}<{a}>{b}</{a}>'
return f'{" "*c}<{a}>\n{" "*(c+1)}{traverse(b, c+1)}\n{" "*c}</{a}>'
html = HTML()
@html.div
@html.p
@html.strong
def get_text(name):
return "lorem ipsum, {0} dolor sit amet".format(name)
print(traverse(get_text("John")))
输出:
<div>
<p>
<strong>lorem ipsum, John dolor sit amet</strong>
</p>
</div>
答案 1 :(得分:0)
感谢大家的贡献。最终我结束了这个。 答案中的egt_stack_size
How do I get the current depth of the Python interpreter stack?(第二个答案,我不知道是否有直接链接)
import sys
TAB=" "
def get_stack_size():
size = 2 # current frame and caller's frame always exist
while True:
try:
sys._getframe(size)
size += 1
except ValueError:
return size - 1 # subtract current frame
def p_decorate(func):
def func_wrapper(name):
ind=get_stack_size()-2
ret = ind*TAB+"<p>\n"+ \
"{0}\n".format(func(name))+ \
ind*TAB+"</p>"
return ret
return func_wrapper
def strong_decorate(func):
def func_wrapper(name):
ind=get_stack_size()-2
ret = ind*TAB+"<strong>\n"+ \
"{0}\n".format(func(name))+ \
ind*TAB+"</strong>"
return ret
return func_wrapper
def div_decorate(func):
def func_wrapper(name):
ind=get_stack_size()-2
ret = ind*TAB+"<div>\n"+ \
"{0}\n".format(func(name))+ \
ind*TAB+"</div>"
return ret
return func_wrapper
#get_text = div_decorate(p_decorate(strong_decorate(get_text)))
@strong_decorate
@div_decorate
@p_decorate
def get_text(name):
ind=get_stack_size()-2
return ind*TAB+"lorem ipsum, {0} dolor sit amet".format(name)
print(get_text("John"))
正如@brunodesthuilliers指出的那样,排雷可能不是最好的方法。 @ Ajax1234我担心您的标签对我不起作用,因为开始和结束标签不仅是一个单词,而且是一个句子,因此我应该处理标签的名称以获得正确的“标签”,但是您的标签是一个很好的练习这样可以节省很多代码:-)