2012-05-24 1 views
7

현재 모듈이 "top level scripting environment"__main__ 인 경우에도 함수의 실제 현재 모듈을 가져 오려고합니다 (다른 곳에서 가져온 경우).Python : 현재 모듈을 확인하십시오 (__main__이 아님)

이상하게 들릴지 모르겠지만, 배경은 기능을 직렬화하고 다른 컴퓨터에서 (인수를 포함하여) 직렬화를 해제해야하는데 올바른 모듈인지 확인해야합니다. __main__ deserialize하기 전에 가져옵니다 (그렇지 않으면 AttributeError: 'module' object has no attribute my_fun이라는 오류가 발생합니다).

지금까지, 나는 inspection을 시도했다 :

import inspect 
print inspect.getmodule(my_fun) 

나에게 물론

<module '__main__' from 'example.py'> 

을 제공한다. 나는 또한 globals(), 행운을 사용하여 유용한 것을 찾는 시도했다.

내가 정말로 원하는 것은 <module 'example' from 'example.py'>입니다. 나는 해키 방법은

m_name = __main__.__file__.split("/")[-1].replace(".pyc","") 

같은 것을 사용하여 파일 이름에서 구문 분석 한 후 이름 sys.modules[m_name]으로 모듈을 찾을 수있을 것 같아요.

더 깨끗한/더 좋은 방법이 있나요?

편집 : ipython의 "FakeModule"과 좀 더 인터넷 검색에 대한 학습 후, 나는 내가 명시 적으로 현재 모듈을 가져 오는 것이 나의 현재 솔루션 (포함 직면하고있어 정확하게 문제를 설명하는 this post 건너 온 import current_module 및 my_fun 대신 current_module.my_fun을 직렬화). 내 패키지 사용자에게는 직관적이지 않을 수도 있으므로이 문제를 피하려고합니다.

+0

'nose' 라이브러리의 내부, 특히'importer' 모듈을 살펴 보셨습니까? '코 (nose) '는 이것과 매우 유사한 것들을하기 때문에 영감을 찾는 좋은 장소 일 수 있습니다. –

답변

3

실제로이 동일한 문제가 발생했습니다. 내가 사용하는 어떤

했다 : 효과적으로 같은

return os.path.splitext(os.path.basename(__main__.__file__))[0] 

어느 "해킹." 솔직히, 나는 그것의 최선의 해결책이라고 생각한다.

+0

감사합니다. Winston, 제가 함께 간 해결책입니다. 그 이후로 어떤 불쾌한 문제에도 부딪치지 않았습니다. – soramimo

+0

"bar/foo.py"와 같은 폴더 내에서 스크립트를 실행하는 경우에는 작동하지 않습니다. – jwayne

+0

@jwayne 대신에 무엇이 생성됩니까? –

2

당신이 이것을 할 수있는 한 가지 방법은 - 아마도 최선의 방법은 아니지만, 저에게 효과적입니다 - 모듈을 __import__으로 가져오고 getattr을 다음과 같이 사용하는 것입니다.

(여기서 나는 this post에 대해 동적으로로드 모듈에 설명 된 몇 가지 아이디어를 사용하고 있습니다.)

def dynamic_import(name): 
    mod = __import__(name) 
    components = name.split('.') 
    for comp in components[1:]: 
     mod = getattr(mod, comp) 
    return mod 

tmodule = dynamic_import('modA') 
# Print the module name 
print tmodule 
# Use the module's contents 
t = tmodule.myObject() 
t.someMethod() 

modA.py은 다음과 같다 여기서

class myObject(): 
    def someMethod(self): 
     print "I am module A" 

그래서 우리가 있어요 볼 수 있습니다 우리가 가져온 모듈의 이름과 정상적인 방법으로 모듈 내부의 객체와 메소드를 계속 사용하려고합니다. 나는이 프로그램을 실행할 때 나는 다음과 같은 얻을 :

python experiment.py 
<module 'modA' from 'modA.pyc'> 
I am module A 

다시 말하지만,이 또는하지 않을 수있다 "이상적인"방법,하지만 지금까지 내가 대부분 바람직하지 않은 절충을 수반하지 않는 말할 수있는 잘 작동합니다 사례. 희망이 도움이됩니다.

3

원본 솔루션이 가장 좋고 간단하다고 생각합니다. 귀하의 사용자에게 반 직관적 인 것처럼 보이는 것에 대해 걱정한다면, 그것을 멋진 기능으로 포장하고 그것이 무엇인지를 문서화하십시오.

모듈을 __main__으로 실행하면 파이썬은 실제로 모듈을 일반 모듈 이름과 연결하지 않습니다. import example 인 경우 모듈은 별도의 모듈 인 것처럼 두 번째로 파일을로드합니다. 실제로 이것은 아마도 여러분의 경우에 발생합니다. 그렇지 않으면 sys.modules에서 모듈을 이름으로 찾을 수 없습니다 : 모듈 example 및 모듈 __main__은 실제로 모듈 변수를 명시 적으로 변경하면 알 수 있듯이 실제로는 별도의 런타임 객체입니다. 그들 중 하나.

3

나는 구식이라고 알고 있지만 파이썬 3에서 저에게 도움이되는 더 간단한 해결책을 발견했습니다. 간단히 말해서, 객체의 __spec__이 있습니다.이 객체는 "__main__"이 아닌 실제 모듈 이름도 저장합니다.

import inspect 
if obj.__class_.__module__ == "__main__": 
    print(inspect.getmodule(obj).__spec__.name) 
+0

이것은 ('python -m'으로) 모듈로 실행될 때만 작동합니다. 그렇지 않으면'__spec__'는'None'입니다.'.foo'는'.foo'가 아닌'foo'를 제공합니다. 그러나 그것은 나를 위해 충분하다! (또한 유스 케이스의 경우'inspect'을 건너 뛰고'import __main__; print (__ main __.__ spec __. name)'을 사용하면됩니다.) –

관련 문제