2012-12-03 3 views
1

주어진 모듈의 클래스 인스턴스 인 현재 네임 스페이스의 모든 객체를 피클 링하는 함수를 작성하고 싶습니다. 아이디어는 ipython 세션 동안 사용자가 mymodule에서 많은 객체를 생성하고 모든 객체를 빠르게 저장해야 할 수도 있다는 것입니다.주어진 모듈에서 모든 객체를 pickle 처리하는 함수

때문에, 예를 들어 내가 나의 첫 번째 시도 (아래 보여,이

from mymodule import cat, dog, pickle_all 
c= cat(), d=dog() 
pickle_all('killer_sesh.p') 

최종 세션 같은 것이, 새 세션을, 한 달 동안 잊어 다시 와서 시작

from mymodule import upickle_all 
objs = unpickle_all('killer_sesh.p') 

을 원하는)는 현재 네임 스페이스에 붙여 넣을 때 작동합니다. 함수로 정의하거나 mymodule과 같이 다른 곳에 넣으면 dir() 명령은 현재 네임 스페이스를 반환하지는 않지만 함수가 표시하는 네임 스페이스를 반환합니다. dir()의 결과를 인수로 전달하더라도 해당 함수 내에서 객체를 사용할 수 없습니다.

import pickle 
filename= 'killer_sesh.p' 
module='mymodule' 
module_objects = {} 
for k in dir(): 
    try: 
     if eval(k).__module__.split('.')[0] == module: 
      if k[0]!='_': 
       print(k) 
       module_objects[k] = eval(k) 
    except(AttributeError): 
     pass 
    file= open(filename,'w') 
pickle.dump(module_objects, file) 
file.close() 

이 같은 기능입니까?

+2

'eval()'와 같은 것 - 그것을하는 나쁜 방법입니다. 'getattr()'을 한번보세요. –

+1

+1 to Lattyware 님의 의견 또한,'dir'을 수동으로 반복하고 그것으로 무엇을해야 할지를 결정하기보다는'inspect' 모듈을 사용하기를 원할 것입니다. – abarnert

+0

두 가지 모두 좋은 제안이지만 실제 문제는 함수 네임 스페이스 외부의 개체에 액세스하는 것입니다. – alex

답변

1

내가 함수로 정의하거나 mymodule과 같이 다른 곳에두면 dir() 명령은 현재 네임 스페이스를 반환하지 않지만 함수에서 보이는 네임 스페이스를 반환합니다. dir()의 결과를 인수로 전달하더라도 해당 함수 내에서 객체를 사용할 수 없습니다.

맞아요. 그 이유는 현재 사용자가 eval을 사용하여이를 평가하고 있기 때문입니다. 현재 평가 결과는 현재 네임 스페이스에서 평가됩니다. 일 수 있으며 globalslocals을 다른 메인 스페이스에서 전달하고 해당 매개 변수를 사용하여 eval을 호출하십시오. 즉, foo(dir()) 대신 foo (dir(), globals(), locals())`가 사용됩니다.

그러나 전체 디자인은 좋지 않습니다. eval을 사용하여 범위 멤버를 얻는 것은 좋지 않습니다. 사실 eval을 거의 으로 사용하면 무엇이든은 좋지 않습니다.

더 나은 해결책은 회원을 평가하고자하는 것을 전달하고 getattr을 사용하여 얻는 것입니다.

더 나은 해결책은 dir을 사용하지 않고 그 이름으로 속성을 얻는 방법을 찾는 것입니다. 물건을 검사하려면 inspect 모듈이 필요합니다. (심지어 inspect이 제공하지 않는 것을하고자 할 때조차도 문서에서 링크 된 소스 코드를 읽는 것이 일반적으로 최선의 방법을 알려줄 것입니다.)

+0

'locals()'의 출력을 전달하면 네임 스페이스 문제가 해결되고'inspect' 모듈은 실제로 usefule입니다 소스 모듈을 결정할 때. – alex

관련 문제