2

问题:如何终止实例化或确保创建 python 通用 feedparser 的新实例化?


信息:

我现在正在开发一个程序,该程序可以下载和编目大量博客。它运行良好,除了一个不幸的错误。我的代码设置为获取博客网址列表并通过 for 循环运行它们。每次运行它都会选择一个 url 并将其发送到一个单独的类,该类管理数据的下载、提取和保存到文件。

第一个网址工作得很好。它下载整个博客并将其保存到文件中。但是它下载的第二个博客也将包含第一个博客的所有数据,我完全不知道为什么。


代码片段:

class BlogHarvester:
  def __init__(self,folder):
    f = open(folder,'r')
    stop = folder[len(folder)-1]
    while stop != '/':
        folder = folder[0:len(folder)-1]
        stop = folder[len(folder)-1]
    blogs = []
    for line in f:
        blogs.append(line)

    for herf in blogs:
        blog = BlogParser(herf)
        sPath = ""
        uid = newguid()##returns random hash.
        sPath = uid
        sPath = sPath + " - " + blog.posts[0].author[1:5] + ".blog"
        print sPath
        blog.storeAsFile(sPath)

class BlogParser:
  def __init__(self, blogherf='null', path='null', posts = []):
    self.blogherf = blogherf

    self.blog = feedparser.parse(blogherf)
    self.path = path
    self.posts = posts
    if blogherf != 'null':
        self.makeList()
    elif path != 'null':
        self.loadFromFile()

class BlogPeices:
  def __init__(self,title,author,post,date,publisher,rights,comments):
    self.author = author
    self.title = title
    self.post = post
    self.date = date
    self.publisher = publisher
    self.rights = rights
    self.comments = comments

我包含了我认为可能有用的片段。抱歉,如果有任何令人困惑的工件。这个程序一直很痛苦。

4

2 回答 2

1

问题是posts=[]。默认参数是在编译时计算的,而不是在运行时计算的,因此对象的突变会在类的生命周期内保持不变。而是使用posts=None和测试:

if posts is None:
  self.posts = []
于 2010-01-17T05:28:10.747 回答
0

正如 Ignacio 所说,函数列表中的默认参数发生的任何突变都将在类的生命周期中保留。

来自http://docs.python.org/reference/compound_stmts.html#function-definitions

执行函数定义时评估默认参数值。这意味着表达式在定义函数时计算一次,并且每次调用都使用相同的“预计算”值。当默认参数是可变对象(例如列表或字典)时,这一点尤其重要:如果函数修改了对象(例如,通过将项目附加到列表中),则默认值实际上已被修改。这通常不是预期的。解决这个问题的一种方法是使用 None 作为默认值,并在函数体中显式测试它。

但这带来了一个问题,你正在修改一个引用......所以你可能正在修改一个列表,该列表的类的消费者预计不会被修改:

例如:

class A:
  def foo(self, x = [] ):
    x.append(1)
    self.x = x

a = A()
a.foo()
print a.x
# prints: [1]
a.foo()
print a.x
# prints: [1,1]   # !!!! Consumer would expect this to be [1]
y = [1,2,3]
a.foo(y)
print a.x
# prints: [1, 2, 3, 1]
print y
# prints: [1, 2, 3, 1]  #  !!!! My list was modified

如果您要复制它:(请参阅http://docs.python.org/library/copy.html

import copy
class A:
  def foo(self, x = [] ):
    x = copy.copy(x)
    x.append(1)
    self.x = x

a = A()
a.foo()
print a.x
# prints: [1]
a.foo()
print a.x
# prints: [1]   # !!! Much better =)
y = [1,2,3]
a.foo(y)
print a.x
# prints: [1, 2, 3, 1]
print y
# prints: [1, 2, 3]  #  !!!! My list is how I made it
于 2010-01-17T05:59:39.827 回答