2013-02-06 4 views
0

에서 가져올 위치를 결정하는 데 도움이되는 Python 스크립트/함수를 작성하려고합니다. 이 기능을 PyQt4 용으로 특별히 만들고 싶지만 을 확장하여 Python 표준 라이브러리에 유용하게 사용할 수 있습니다.가져 오기 위치를 검색 중

이 작업을 수행하려면 모듈, 공유 객체, 클래스 및 주어진 검색 용어에 대해 더 많은 '유형'을 동적으로 검색해야합니다.

모듈/클래스/등을 전달하고 싶습니다. 문자열로 동적으로 가져온 다음 검색하십시오.

search(object_to_search, search_term) 

예 : :이 또한 sys.path을 모두 검색 '*'와 같은 와일드 카드를 지원할 수있는 가정

search('datetime', 'today') -> 'datetime.datetime.today' 

search('PyQt4', 'NonModal') -> 'PyQt4.QtCore.Qt.NonModal' 

search('PyQt4', 'QIcon') -> 'PyQt4.QtGui.QIcon' 

함수의 인터페이스는 다음과 같이 될 것이다 그러나 이것은 내가이 시간에 대해 생각하고있는 것의 범위를 벗어납니다.

이 유형의 스크립트는 PyQt4에 특히 유용합니다. 위의 NonModal과 같은 '열거 형'항목이 많으며 을 가져올 위치를 찾거나 참조하는 것이 번거로울 수 있습니다.

이후 Python으로 정보를 쉽게 번역 할 수 있기 때문에 C++ Qt 문서를 PyQt4 정보에 사용하는 경향이 있습니다. C++ Qt 설명서가 더 포괄적입니다. Qt가 적절하게 사용하기 위해 샘플 코드 을 찾는 것이 훨씬 쉽습니다. 그러나 일부 'enum-like'특성의 가져 오기 위치는 수동으로 문서를 검색하거나 추측하지 않고 PyQt4에서 찾기가 어렵습니다. 목표는이 프로세스를 자동화하고 스크립트에서 에게 내가 찾고있는 위치를 알려주는 것입니다.

난 그냥 재귀 dir()와 객체를 탐색 inspect 모듈을 사용하여 포함하여이를 구현하는 몇 가지 방법, 공유 객체에 대한 가져 오기/발견의 해키 버전을 시도했다. 아래는 제 다양한 구현입니다. 실제로는 그렇지 않습니다.

이런 종류의 것이 가능합니까? 그렇다면이 작업을 수행하는 가장 좋은 방법은 무엇입니까? 또한, 내장 된 것들, 함수 등을 생략하여 검색하는 항목의 수를 줄이려고했지만, 이것이 필요하거나 이 맞는지 확신 할 수 없습니다.

시도했습니다 해결책 : pydoc이 모듈에 볼 수있는 힌트 @JonClements에

def search_obj_inspect(obj, search_term): 
    """Search given object for 'search_term' with 'inspect' module""" 

    import inspect 

    def searchable_type(obj): 
     is_class = inspect.isclass(obj) 
     root_type_or_obj = is_class and obj not in [object, type] 
     abstract_class = is_class and inspect.isabstract(obj) 
     method_or_func = inspect.ismethod(obj) or inspect.isfunction(obj) 
     try: 
      hidden_attribute = obj.__name__.startswith('__') 
     except AttributeError: 
      hidden_attribute = False 

     searchable = True 

     # Avoid infinite recursion when looking through 'object' and 'type' b/c 
     # they are members of each other 
     if True in [abstract_class, root_type_or_obj, hidden_attribute, 
        method_or_func, inspect.isbuiltin(obj)]: 
      searchable = False 

     return searchable 


    # FIXME: Search obj itself for search term? obj.__name__ == search_term? 
    for n, v in inspect.getmembers(obj, 
            predicate=lambda x: searchable_type(x)): 
     if search_term in n: 
      try: 
       return v.__name__ 
      except AttributeError: 
       return str(v) 

    return None 


def search_obj_dir(obj, search_term): 
    """Search given object and all it's python submodules for attr""" 

    import re 
    import types 
    SEARCHABLE_TYPES = (types.ModuleType, types.ClassType, types.InstanceType, 
         types.DictProxyType) 

    for item in dir(obj): 
     if item.startswith('__'): 
      continue 

     if re.search(search_term, item): 
      return obj.__dict__[item].__module__ 
     else: 
      try: 
       submod = obj.__dict__[item] 
      except (KeyError, AttributeError): 
       # Nothing left to recursively search 
       continue 

      if not isinstance(submod, SEARCHABLE_TYPES): 
       continue 

      #mod = search_obj_dir(submod, search_term) 
      #if mod: 
       #return '.'.join([mod, submod.__name__]) 

    return None 


def search_so(module, attr): 
    """Search given modules shared objects for attr""" 

    import os 
    import re 

    try: 
     path = module.__path__[0] 
    except (AttributeError, IndexError): 
     return False 

    for root, dirs, files in os.walk(path): 
     for filename in files: 
      if filename.endswith('.so'): 
       py_module_name = filename.split('.')[0] 
       so_module = __import__(module.__name__, globals(), locals(), 
             [py_module_name]) 

       if re.search(attr, py_module_name): 
        return ''.join([module.__name__, '.', py_module_name]) 
       try: 
        found = search_obj_dir(
            so_module.__dict__[py_module_name], attr) 
       except KeyError: 
        # This isn't a top-level so, might be a subpackage 
        # FIXME: Could recursively search SO as well, but imports 
        #  might get weird 
        continue 

       if found: 
        return found 
+0

내 스크립트의 '전체'코드는 다음에서 볼 수 있습니다. [https://gist.github.com/durden/4723305](https://gist.github.com/durden/4723305) –

+0

귀하의 게시물 그래서 당신은 코멘트를 사용하지 않아도됩니다;) –

+0

@ NadirSampaoli 나는 그것이 메인 포스트에 보완 적이라고 느꼈기 때문에 나는 단지 코멘트로 게시하고 싶었어요. –

답변

0

감사합니다. pkgutilinspect 모듈을 조합하여 원하는 것을 얻을 수있는 방법을 찾았습니다.

'트릭'은으로 패키지의 모든 모듈 (예 : PyQt4)을 통과 한 다음 패키지가 아닌 모든 객체를 inspect.getmembers으로 검색 할 수 있습니다. 일반적인 아이디어는 다음과 같습니다.

for pkg in given_pkg: 
    for module_or_class in pkg: 
     for attribute in module_or_class: 

전체 솔루션 here을 볼 수 있습니다.

관련 문제