【发布时间】:2016-09-29 09:02:19
【问题描述】:
我真的很讨厌样板。但是,我不能否认像下面这样的代码是一个巨大的好处。所以我的问题是,在 Python 中做了什么来弥补它没有附带宏(模板)预处理器的事实?
一个想法是编写一个工厂函数,但我愿意承认我不知道从哪里开始。 (请注意,这是 Django,它的声明性类和有趣的“神奇”元类东西在下面进行,我知道足以识别它们,但如果我破坏它,则不足以理解或调试)
另一种方法是将其转换为模板并通过一个简单的预处理器导入它,该预处理器在 Bash 中实现了 ${var:-default} 之类的东西。 (见What is an alternative to execfile in Python 3?),
with my_preprocessor("somefile.py") as f:
code = compile(f.read(), "somefile.py", 'exec')
exec(code) # in the current namespace
但是这些年来我看到了很多关于exec 的警告。引用的 SO 答案提到调试的行号是一个问题。然后是 http://lucumr.pocoo.org/2011/2/1/exec-in-python/ ,警告包括内存泄漏在内的细微问题。我怀疑它们不适用于定义“永不”删除的类的代码,但另一方面,我不希望在生产环境中引入晦涩的问题。
欢迎提出任何想法或建议。最好的办法是接受剪切和粘贴样板吗?任何此类模板的粘贴修改都不可能超过 20 次,通常少于 10 次。
示例代码。标有#V 的行是唯一通常会定制的行。前两个类只被第三个使用一次。
#--- this is boilerplate for a select-view ----
#--- just replace the string "User" by the relevant model and customize
class UserSelectPopupTable( tables.Table):
id = SelectorColumn( clickme='<span class="glyphicon glyphicon-unchecked"></span>' ) #V
class Meta:
model=User
attrs={ 'class':'paleblue' }
empty_text='Sorry, that search did not match anything.'
fields=( 'name','address', ) #V
sequence=('id','name','address',) #V
class UserFilter2(django_filters.FilterSet):
name = django_filters.CharFilter(lookup_expr='icontains') #V
address = django_filters.CharFilter(lookup_expr='icontains') #V
class Meta:
model = User
fields = ('name','address', ) #V (usually same as previous)
class UserSelectPopup( FilterTableView ):
model=User
table_class=UserSelectPopupTable
filterset_class=UserFilter2
template_name='redacted/select_in_popup.html'
#--- end boilerplate
【问题讨论】:
-
你能举例说明你想如何使用这些生成的类吗?
-
作为视图:
url(r'^UserSelectPopup/$', views.UserSelectPopup.as_view(), name ='userselectpopup'), -
编写工厂比我想象的要容易得多。我阅读并重新阅读
type3-arg 文档,然后......经过更多测试和整理后将回答自己的问题。
标签: python django python-3.x boilerplate