使用内置类型(,,)函数创建动态模块

时间:2010-08-11 13:19:21

标签: python module metaprogramming python-module

我正在尝试使用type(,,)函数动态构建模块。该模块创建表示模板的类,我需要为存在于特定文件夹中的每个.tex文件创建一个新类。例如,如果我有一个a4-page-template.tex文件,我需要创建一个名为A4PageTemplate的类。

我可以使用type语句轻松创建类型;我到目前为止看起来像这样;

#
# dynamictypes.py
# 
import os, re

_requiredEnd = "-template.tex"
_packageDir = "C:\\Users\\...";

def _getClassName(name):
  return re.sub("-(.)", lambda m: m.group(1).upper() , name) + "Template"

for file in os.listdir(_packageDir):
  if file.lower().endswith(_requiredEnd):
    _fileWithoutExt = file[:-len(_requiredEnd)]
    _className = _getClassName(_fileWithoutExt)
    _newClass = type(_className, (object,), dict(template=file))
    print _newClass

注意倒数第二行创建类型,其后面的print语句显示已为每个模板创建了一个类型;

<class 'dynamictypes.PandocA4BookTemplate'>
<class 'dynamictypes.PandocBookTemplate'>
<class 'dynamictypes.PandocCompactTemplate'>

然而,当我使用该模块时,我无法使用该类型;如果我写这个消费者脚本;

import dynamictypes

myTemplate = dynamictypes.PandocA4BookTemplate()

我收到此错误;

Traceback (most recent call last):
  File "C:\Users\steve.cooper\Desktop\driver.py", line 3, in <module>
    myTemplate = dynamictypes.PandocA4BookTemplate()
AttributeError: 'module' object has no attribute 'PandocA4BookTemplate'

你能想到一种方法让我将我创建的类型添加到模块中,这样它就是模块的第一类吗?

1 个答案:

答案 0 :(得分:3)

您已创建新类并将其分配给全局变量_newClass,但您不存储此变量!请注意,如果执行dynamictypes._newClass,您将获得最终类型。

在创建它时,您需要创建一个变量来保存每个新类:

globals()[ _className ] = _newClass

这会将_className注册为模块中的全局变量,以便您可以从外部访问它。

顺便说一下,你的正则表达式在a4-page-template.tex上失败了 - 你得到a4PageTemplate而不是A4PageTemplate