2017-03-09 7 views
4

코드가 import posix 일 때 장면 뒤에서 (CPython 3.6.0에서) 어떻게됩니까? 이 모듈에는 __file__ 속성이 없습니다. 상세 모드에서 인터프리터를 시작할 때, 나는이 라인 참조 : 그것은 새로 openened 통역에 이미 sys.modules에서의/`어떻게`posix`라는 이름이 import 문에 의해 해석 되는가?

import 'posix' # <class '_frozen_importlib.BuiltinImporter'> 

을하고 가져 오기는 단지 기존 모듈에 이름을 바인드합니다.

내 플랫폼에서 구현 세부 사항 os.lstat을 살펴보고 os.stat을 사용하는 경우와 사용시기를 결정하려고합니다.

+1

소스 코드를 찾고 계시다면 [여기] (https://github.com/python/cpython/blob/master/Modules/posixmodule.c#L2420)이며 C 언어로되어 있습니다. – user2357112

+0

감사. 또한 C 코드가 파이썬 객체에 바인딩되는 방법을 배우는 데 관심이 있습니다. – wim

답변

3

여기에는 필요한 것보다 자세하게 설명되어 있습니다.


posix은 내장 모듈입니다. "built-in module"이라고 들으면 일반 표준 라이브러리 모듈을 생각할 수도 있고 C로 쓰여진 모듈을 생각할 수도 있지만 posix은 대부분 내장 된 것보다 더 많이 내장되어 있습니다.

posix 모듈은 C로 작성되었으며 Modules/posixmodule.c입니다. 그러나 대부분의 C 모듈 (표준 라이브러리 C 모듈조차도)은 .so 또는 .pyd 개의 파일로 컴파일되고 일반 파이썬 모듈과 마찬가지로 가져 오기 경로에 배치되지만 posix은 실제로 Python 실행 파일 자체로 컴파일됩니다. CPython과의 수입 시스템의 내부 부품의


하나는 PyImport_Inittab array이다

extern struct _inittab _PyImport_Inittab[]; 

struct _inittab *PyImport_Inittab = _PyImport_Inittab; 

이것은 명과 모듈에 대한 C 모듈 초기화 기능 구성 struct _inittab S의 배열 인 그 이름. 여기에 나열된 모듈은 내장되어 있습니다.

이 배열은 처음에 Modules/config.c (또는 사용자의 OS에 따라 PC/config.c)에서 가져 오는 _PyImport_Inittab으로 설정되어 있지만 여기서는 그렇지 않습니다. 불행하게도, Modules/config.c 파이썬 빌드 과정에서 Modules/config.c.in에서 생성됩니다, 그래서 나는 당신에게 소스 코드 링크를 보여 주지만, 여기 내가 파일을 생성 할 때의 모습의 일부 수 없습니다 당신이 볼 수 있듯이

struct _inittab _PyImport_Inittab[] = { 

     {"_thread", PyInit__thread}, 
     {"posix", PyInit_posix}, 
     // ... 

을 모듈 초기화 함수 PyInit_posix과 함께 posix 모듈에 대한 항목이 있습니다. 모듈을로드 할 때


가져 오기 시스템의 일환으로, 파이썬, sys.meta_path을 통해 모듈 finders의 목록을 간다. 이 찾기 사용자 중 하나는 익숙한 sys.path 검색을 수행하지만 그 중 하나는 _frozen_importlib.BuiltinImporter이며 posix과 같은 기본 제공 모듈을 찾습니다. "posix" 이름을 PyImport_Inittab를 검색 _imp.is_builtin를 사용

@classmethod 
def find_spec(cls, fullname, path=None, target=None): 
    if path is not None: 
     return None 
    if _imp.is_builtin(fullname): 
     return spec_from_loader(fullname, cls, origin='built-in') 
    else: 
     return None 

: 파이썬은 그 찾기를 시도 할 때, 파인더의 find_spec 방법을 실행합니다. 검색은 이름을 찾습니다. 따라서 find_spec은 내장 모듈의 로더가이 모듈 작성을 처리해야한다는 사실을 나타내는 모듈 스펙을 리턴합니다.(로더는 spec_from_loader에 두 번째 인수 인 BuiltinImporter 파인더와 로더가 모두 있기 때문에 그것은, 여기 cls입니다..)

파이썬은 모듈 객체 생성하기 위해 로더의 create_module 메소드를 실행

:

@classmethod 
def create_module(self, spec): 
    """Create a built-in module""" 
    if spec.name not in sys.builtin_module_names: 
     raise ImportError('{!r} is not a built-in module'.format(spec.name), 
          name=spec.name) 
    return _call_with_frames_removed(_imp.create_builtin, spec) 

대표를 을 _imp.create_builtin으로 변경하여 모듈 이름으로 PyImport_Inittab을 검색하고 해당 초기화 함수를 실행합니다.

(_call_with_frames_removed(x, y) 단지 x(y) 호출하지만 당신은 당신의 수입이 잘못 스택 추적에서 그 프레임을 보지 못할 이유가 스택 추적에서 importlib 프레임을 제거하는 마법의 표시 등 part of the import system 취급을.)


코드 경로를 더보고 싶다면 Lib/importlib/_bootstrap.py, 임포트 구현의 대부분이 존재하는 Python/import.c, 구현의 C 부분 대부분이있는 곳, 바이트 코드 인터프리터 인 Python/ceval.c을 볼 수 있습니다. 루프가 생겨서, 따라서 import 명세서가 가져 오기 기계의 더 핵심 부분에 도달하기 전에 시작됩니다.

관련 문서에는 section of the language reference on the import system과 PEP 451302이 포함됩니다. a bit of documentationPyImport_Inittab을 수정하려고하고 다른 사람들은 Python을 다른 프로그램에 포함시키는 사람들을 대상으로했지만 sys.builtin_module_names 목록이 있습니다.