2012-11-13 3 views
2

초기화 모듈 내에서 함수 호출을 PYTHONPATH에 패치하여 현재 디렉토리를 추가하는 데코레이터로 래핑합니다. 따라서 PYTHONPATH에 패키지를 명시 적으로 추가하는 것에 대한 걱정없이 모듈 내에서 상대적 가져 오기를 사용할 수 있습니다. PYTHONPATH (패브릭 작업 사용시) 패치

@patch_python_path 
def initialize(): 
    #at this point any code being run has access to local modules through relative imports 
    pass 

내가 인식하지 나는이 방법으로 모든 주요 문제가 있습니까 : 여기

def patch_python_path(f): 
    @wraps(f)  
    def wrap(*args, **kwargs): 
     ROOT = os.pathsep.join([os.path.abspath(os.path.dirname(__file__))]) 
     if not os.environ.has_key("PYTHONPATH"): 
      os.environ["PYTHONPATH"] = "" 
     if not (ROOT in os.environ["PYTHONPATH"].split(":")): 
      os.environ["PYTHONPATH"] = "%s:%s" % (os.environ["PYTHONPATH"], ROOT) 
     if not ROOT in sys.path: 
      sys.path.append(ROOT) 
     return f(*args, **kwargs) 
    return wrap 

내가 그것을 사용하는 방법 (@의 abarnert의 의견에 따라 편집)? 이와


내 목표는 다음과 같다 :

  • 내가 자기가 사용자가 즉시 나는 또한 사용자가 할 수 있다고 가정
  • 추가 ENV 조작없이 사용할 수있는 부트 스트랩 포함 갖고 싶어 부트 스트랩 패키지의 이름을 변경하여 모든 가져 오기가 상대적인 상태로 유지되도록해야합니다.

[편집] 실제로 내가 문제가 있다는 것을 깨닫고 있습니다. Fabric이 순수 파이썬 모듈 가져 오기와 반대로 작업을 실행하는 방식과 관련이 있습니다. 파이썬 셸 (팹 task1과 반대)에서 작업을 실행하려고하면 모든 패치가 필요하지 않고 모든 가져 오기가 올바르게 해결됩니다. 당신은 단순히 sys.path에 현재 경로를 추가 할 수 있습니다 팹 원인 가져 오기 오류

+0

명확해야 : 사용자가 패키지를 설치하지 않고 현재 디렉토리에 패키지를 드롭하고 사용할 수있게하려면? – abarnert

+0

예. 좀 더 구체적으로 말하자면 부트 스트랩 상용구 역할을하는 장고 기반 웹 애플리케이션이다. 사용자 클론 일반 버전, 조정 및 그냥 작동 –

답변

1

을 통해 작업을 실행 :

import sys 
def patch_python_path(f): 
    def wrap(*args, **kwargs): 
     if not '.' in sys.path: 
      sys.path.append('.') 
     return f(*args, **kwargs) 

    return wrap 
+0

실제로이'f '어디서나 호출하지 않는 외에, OP는 이미'sys.path'를 수정하고 있으므로, 나는 이것이 그에게 아무것도 가르치고 있다고 생각하지 않습니다. 모르겠다. 또한, "합법적 인"것이라고 부르는 것은 모든 문제에 대해 유익하고, OP는 그가 그릇된 행동을하지 않는다고 생각하게 만듭니다. – abarnert

+0

@abarnet 의견을 주셔서 감사합니다. 나는 당신의 제안에 따라 나의 대답을 업데이트했다. – btel

+0

텍스트 "현재 경로를'sys.path '에 추가하는 것은 여전히 ​​OP가 벌써하고있는 일입니다. (게다가, 그것은 _your_ 코드와 일치하지 않고 대신'sys.path'에'.'을 추가합니다. 그러나 덜 심각한 문제입니다.) – abarnert

2
  1. os.environ하는 세계입니다. 당신은 그것을 수정하고 나중에 다시 수정하지 않습니다. 따라서 어떤 함수에서 @patch_python_path을 수행 한 후에는 다른 모듈과 최상위 스크립트를 포함하여 그 이후 정의한 모든 것에 대해 동일한 작업을 수행했습니다.
  2. sys.path 또한 글로벌이며 다시 수정하고 복원하지 않습니다.
  3. PYTHONPATHsys.path을 모두 수정하지 않아야합니다. (특히 당신이 필요로하지 않는 전자입니다.)
  4. PYTHONPATH.을 추가하고 있지만 os.getcwd()sys.path으로 추가하고 있습니다. 언제든지 을 수행하면을 모두 수정해야하며 os.chdir() 이후의 모든 작업이 중지되어 PYTHONPATH은 효과적으로 변경되지만 sys.path은 효과적으로 변경되지 않습니다.
  5. 래핑 된 함수는 docstring, name 등을 잃게됩니다. wrap 기능에서 @functools.wraps을 사용하십시오.

처음에는 좋은 아이디어인지 아닌지에 관계없이 모두 구현과 관련된 문제입니다.

사람들은 (a) Python XY 패키지를 Python VW처럼 작동하게하고 (b) 소스 트리의 패키지를 설치 후 가져 오기와 같은 방식으로 가져올 수있게합니다. 인터프리터 쉘. 전자는 아마도 나쁜 생각 일 것입니다. 후자는 편리하지만 그것을 성취 할 수있는 다른 방법이 있습니다.좀 더 높은 수준의 목표가 있다면, 목표를 달성하기위한 가장 좋은 방법인지 여부를 누군가에게 알리기 전에 그 목표가 무엇인지 말해야합니다.

+0

감사합니다. 나는 달성하려고 노력하고있는 objetives 개요를 내 게시물을 업데이 트했습니다. –

+0

귀하의 의견에 따라. 1 및 2 : 프로젝트 (내 사례)의 기반을 설정하는 데 사용 된 상용구의 문맥에서 environ 및 sys.path를 문제로 수정하는 것을 보지 못했습니다. 지금까지 나는 이들 인터프리터의 범위가 실행중인 인터프리터 인스턴스라는 것을 알고있다. 3 : 'import'문과 다른 파이썬 기반 프로세스가 올바르게 생성되도록 패치 할 필요가있다. (예 : python manage.py runserver --settings = modules.settings) 4와 5 : 좋은 전화 –

+0

@PhilipNuzhnyy : 인터프리터 인스턴스의 범위에 맞게 전역 변수를 수정하려면 최상위 모듈을 가져올 때 함수를 꾸미는 것이 아니라 왜 가져 오는 것이 좋을까요? 훨씬 간단합니다 (함수 중 하나가 수백만 번 호출되어야 할 때 성능 문제는 피할 수 있지만 문제는별로 없습니다). – abarnert