2013-03-31 7 views
1

액면가에서 C-API 함수 PyModule_NewPyModule_NewObject은 분명히 새로운 모듈 객체를 생성합니다.PyModule_New의 목적과 용도

official Python DocumentationPyModule_NewObject에 대한 다음 설명을 제공 :

반환 이름으로 설정 이름 속성을 가진 새 모듈 객체입니다. 모듈의 문서이름이 인 경우에만 채워집니다. 호출자는 파일 속성을 제공 할 책임이 있습니다. 그 대신 PyObject* 문자열, 모듈 이름에 대한 인수로 C 문자열 (char*)를 받아들이는 제외

PyModule_New은 같은 일을한다.

좋아, 그래서 이것은 매우 간단합니다,하지만 ...

내 질문은 : API 함수 PyModule_NewObject 전화의 사용은 무엇인가?

확실히 이론적으로 새로운 모듈을 동적으로 만들고 싶을 때 좋습니다. 그러나 문제는 실제적으로 새로운 모듈 객체를 만든 후에 객체에 메서드, 클래스, 변수 등과 같은 객체를 추가하는 것이 모듈의 __dict__ 속성에 유용하다는 것입니다. 이 방법으로 모듈 사용자는 모듈을 가져 와서 실제로 그 모듈로 무언가를 할 수 있습니다.

문제는 모듈의 __dict__ 속성이 있다는 것이다 읽기 전용 :

>>> import re 
>>> x = re 
>>> re.__dict__ = { "foo" : "bar" } 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: readonly attribute 


그래서, 실제로, 유용 아무것도 할 수있는 방법은 정말 없다 내가 볼 수있는 한 동적으로 만들어진 모듈. 그렇다면 C API 함수의 목적은 무엇입니까 PyModule_New?

답변

2

PyModule_New은 모듈 객체의 생성자입니다. types.ModuleType 클래스의 __new__ 메서드와 마찬가지로 순수한 파이썬 코드에도 노출되어 있습니다.

일반적으로 모듈을 가져 와서 사용자 코드를 사용하기 때문에 사용자 코드에서 그 중 하나를 사용해야하는 경우는 거의 없습니다. 그러나 파이썬 인터프리터가 사용하는 기계는 가져 오기가 요청 될 때 PyModule_New을 사용하여 모듈 객체를 만듭니다.

당신은 import.c in the Python source에서 볼 수 있습니다

새 모듈 객체에 값을 설정하는 방법에 관해서는
/* Get the module object corresponding to a module name. 
First check the modules dictionary if there's one there, 
if not, create a new one and insert it in the modules dictionary. 
Because the former action is most common, THIS DOES NOT RETURN A 
'NEW' REFERENCE! */ 

PyImport_AddModule(const char *name) 
{ 
    PyObject *modules = PyImport_GetModuleDict(); 
    PyObject *m; 

    if ((m = PyDict_GetItemString(modules, name)) != NULL && 
     PyModule_Check(m)) 
     return m; 
    m = PyModule_New(name); 
    if (m == NULL) 
     return NULL; 
    if (PyDict_SetItemString(modules, name, m) != 0) { 
     Py_DECREF(m); 
     return NULL; 
    } 
    Py_DECREF(m); /* Yes, it still exists, in modules! */ 

    return m; 
} 

, 당신은 일반 속성 액세스를 사용할 수 있습니다. (오히려 C 이상) 파이썬 코드에서, 그것은 간단합니다 : 당신이 몇 가지 추가 작업을하지 않는 한이 방법으로 만든 모듈을 다른 곳 가져올 수 없습니다

import types 

mymodule = types.ModuleType("mymodule") 
mymodule.foo = "foo" 

하는 것으로.예를 들어, 당신은 모듈 조회 사전에 sys.modules를 추가 할 수 있습니다 :

import sys 

sys.modules["mymodule"] = mymodule 

이제 다른 모듈 이름으로 mymodule을 가져올 수 있습니다.