Нежелательные feedparser, основанная на Python экземпляр реликвии
Вопрос: как мне убить экземпляр или гарантировать, что я создаю новый экземпляр универсального feedparser python?
Информация:
Я сейчас работаю над программой, которая скачивает и каталогизирует большое количество блогов. Это сработало хорошо, за исключением несчастного жука. Мой код настроен на то, чтобы взять список URL-адресов блога и запустить их через цикл for. при каждом запуске он выбирает url-адрес и отправляет его в отдельный класс, который управляет загрузкой, извлечением и сохранение данных в файл.Первый 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
Я включил фрагменты, которые, как я полагал, будут полезны. Извините, если есть какие-то непонятные артефакты. Эта программа была занозой в заднице.
2 ответа:
Как сказал Игнасио, любые мутации, которые происходят с аргументами по умолчанию в списке функций, останутся на всю жизнь класса.
Из http://docs.python.org/reference/compound_stmts.html#function-definitions
Вычисляются значения параметров по умолчанию когда определение функции является выполненный. Это означает, что выражение вычисляется один раз, когда функция определена, и что то то же самое" предварительно вычисленное " значение используется для каждый вызов. Это особенно важно. важно понимать, когда происходит дефолт параметр-это изменяемый объект, например список или словарь: если функция изменяет объект (например, путем добавление элемента в список), значение по умолчанию фактически изменено. Это вообще не то, что было предназначенный. Способ обойти это-использовать Нет как по умолчанию, и явно испытайте его в теле человека. функция.
Но это вызывает своего рода gotcha, вы изменяете ссылку... Так возможно, вы изменяете список, который потребитель класса, который не должен был быть изменен:
Например:
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