所以我知道在Python中,在方法中声明的变量在它之外是不可见的。但他们的生命周期是什么?我希望每次调用该方法时都会创建一个在方法内声明的变量。
我问因为以下情况。我有一个方法如下(这与cherrypy一起使用,可能不相关,但我仍然会添加它以便以任何方式影响它。)
首先我正在使用的自定义Filter类:
class Filter():
"""
Class used to filter tables displayed in UI, based on few criteria.
Initialize filter with a list of fields, and correspondinf values.
"""
def __init__(self, display_name= "", fields= [], values= [], operations= []):
self.display_name = display_name
self.fields = fields
self.values = values
self.selected = False
self.operations = operations
现在我正在谈论的方法
@cherrypy.expose
@logged()
def getfiltereddatatypes(self, name, filters, datatype):
...some mumbo jumbo...
default_filter = self._get_default_filters(inputTree, name)
#default_filter here can be a object of type Filter if defined or None otherwise
print "RECIEVED " + str(filters)
if default_filter is not None:
print "CREATING NEW"
new_filter = copy.deepcopy(default_filter)
else:
print "CREATING NEW"
new_filter = Filter()
[new_filter.fields.append(value) for value in filters['fields']]
[new_filter.operations.append(value) for value in filters['operations']]
[new_filter.values.append(value) for value in filters['values']]
print "LENGTH =" + str(len(new_filter.fields))
...Some other mumbo jumbo....
所以基本上我想将filters
变量中作为参数接收的过滤器值添加到default_ones。但我希望每次调用该方法时都要这样做,或者为了更好地解释它,我制作了打印件以显示我的问题。所以在第一次调用方法时:
RECIEVED {'operations': ['!='], 'fields': ['model.DataType.subject'], 'values': ['w']}
CREATING NEW
LENGTH =1
正如预期的那样,创建了一个新的Filter对象,并添加了recieved参数中的操作,字段和值,length(fields)= 1.但在我的第二遍:
RECIEVED {'operations': ['!='], 'fields': ['model.DataType.subject'], 'values': ['']}
CREATING NEW
LENGTH =2
现在我无法解释这种行为。正如您所看到的,再次调用if的CREATING NEW brach,filters
变量保存一个项目列表,但结果的长度为2.如果我再次运行它,它将始终递增。就像new_filter = Filter()
调用返回上一个方法调用中的new_filter一样。是什么导致了这种行为?我很兴奋,如果我做了new_filter = copy.deepcopy(Filter())
它可以解决它但我为什么要被迫这样做呢?
此致 波格丹
答案 0 :(得分:5)
def __init__(self, display_name= "", fields= [], values= [], operations= [])
列表仅创建一次。因此,如果您修改它们,下一个调用将具有修改后的列表。如果您不想要此行为,只需使用None
作为默认值并添加如下内容:
if fields is None:
fields = []
self.fields = fields
另一种解决方案是创建一个新列表,无论传递什么:
self.fields = list(fields)
在http://effbot.org/zone/default-values.htm
上还有一篇关于此行为的详细文章顺便说一下,你滥用列表推导并不好。
[new_filter.fields.append(value) for value in filters['fields']]
应该是
new_filter.fields += filters['fields']