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

0 投票
1 回答
1022 浏览
提问于 2025-04-16 02:38

我正在尝试使用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

注意倒数第二行是创建类型的地方,后面的打印语句显示每个模板都创建了一个类型;

<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 个回答

3

你已经创建了一个新的类,并把它赋值给了全局变量 _newClass,但是你并没有保存这个变量!注意,如果你输入 dynamictypes._newClass,你会得到最后创建的类型。

你需要为每个新类创建一个变量来保存它,才能使用:

globals()[ _className ] = _newClass

这会把 _className 注册为模块中的全局变量,这样你就可以在外部访问它了。

顺便提一下,你的正则表达式在处理 a4-page-template.tex 时出错了——你得到的是 a4PageTemplate,而不是 A4PageTemplate

撰写回答