2010-01-17 1 views
2

질문 : 인스턴스화를 죽이거나 파이썬 범용 피드 파서의 새로운 인스턴스 생성을 확실히하려면 어떻게합니까?불필요한 python feedparser 인스턴스 생성 relic


정보 : 내가 지금하는 프로그램에서 일하고 있어요

이 다운로드 및 카탈로그 블로그 많은 수의. 불행한 버그를 제외하고는 잘 작동합니다. 내 코드는 블로그 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 

은 그게 아마 도움이 될 것입니다 생각. 혼란스러운 유물이 있으면 죄송합니다. 이 프로그램은 엉덩이에 통증이있었습니다.

+0

+1 매우 조직적 질문 – jjj

+0

감사합니다.^_^ – Narcolapser

답변

0

이그나시오 말한 것처럼, 기능 목록의 기본 인수에 일어날 어떤 돌연변이가 클래스의 수명있을 것 대신 posts=None 및 테스트를 사용합니다. 함수 정의 실행 인 경우 http://docs.python.org/reference/compound_stmts.html#function-definitions

기본 파라미터 값에서

가 평가된다. 즉, 함수가 정의되고 동일한 "사전 계산 된"값이 각 호출에 대해 사용되는 경우 표현식이 한 번 평가됩니다. 기능 (목록에 항목을 추가 에 의해 예) 객체를 수정하는 경우 기본값은 다음과 같습니다이 기본 매개 변수가 변경 가능한 객체와 같은 목록이나 사전이 때 이해하는 것이 특히 중요하다 효과가 수정되었습니다. 이것은 일반적으로 이 의도 한 바가 아닙니다. 이 문제를 해결하려면 None을 기본값으로 사용하고 함수 본문에 명시 적으로 테스트하십시오.

그러나 이것은 일종의 잡았다가 나오고 참조를 수정하는 중입니다 ...그래서 당신은 목록을 수정 할 수 수정 될 것으로 예상되지 않은 클래스의 소비자 : 예를 들어

:

( http://docs.python.org/library/copy.html 참조) : 대신 복사한다면

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 

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 
+0

하지만 각 루프마다 새로운 blogparser 클래스를 선언하지 않습니까? 아니면 어떻게 지속 되는가? – Narcolapser

+0

함수 foo의 기본 인수는 클래스가 아닌 객체의 수명 동안 유지됩니다. def foo (self, x = []) : 그래서 목록 "[]"의 순간에 대한 참조가 지속됩니다 (그리고 클래스의 각 순간을 참조). – Eld

+0

그게 효과가 있어요. 적어도 하나 이상의 버그를 제거했습니다. 아직도 꽤 일하는 것은 아니지만 나는 다음번에 알아낼 수 있어야합니다. 감사! 이것은 매우 도움이되었습니다. – Narcolapser

1

문제는 posts=[]입니다. 기본 인수는 런타임이 아닌 컴파일 타임에 계산되므로 클래스의 수명 동안 객체에 대한 변이가 유지됩니다.

if posts is None: 
    self.posts = [] 
+0

당신이 무슨 뜻인지 확실하지 않습니다. 조금 더 자세히 설명해 주시겠습니까? 감사. – Narcolapser

+0

코드가 컴파일되고 목록이 변경 가능한 개체가 만들어집니다. 이 목록은 메소드가 호출 될 때마다 게시물로 전달됩니다. 매번 같은 목록입니다. –

+0

감사합니다. 그게 효과가 있었어. 나는 그가 파이썬 문서를 참조했기 때문에 주로 Eld에 답을 주었다. 그것은 저를 위해 진짜로 그것을 한 무슨이었다. 그러나 두 분 모두 매우 도움이되었습니다.^_^ – Narcolapser