如何从python中的给定文本创建一组类及其变量和方法

2024-09-30 16:39:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我想从给定的文本配置创建一组类、变量和方法,特别是django模型,对于exmaple,我有一个要在其中创建的模型列表型号.py你知道吗

     classes=["users", "posts", "commnets"]
     vars= [{"a","b"},{"bb","vv"},{"aa"}]
     #methods=[{....},{....},{....}] not now

在型号.py 我想做这样的东西来创建类

for  i,j in zip(classes,vars):
    create_classes_from_string(i,j)

我如何编程#从#字符串创建#类#以确保它在我的数据库中使用该配置创建表


Tags: django方法py模型文本列表varsusers
1条回答
网友
1楼 · 发布于 2024-09-30 16:39:29

我可以从两个角度来看待这个问题

  1. 动态创建python类的常规方法
  2. 专门创建动态django模型

但在这两种情况下,attrs都应该定义为dict,并带有变量名及其值。因为定义一个没有值的变量在这里毫无意义。你知道吗

1。动态创建python类的常规方法

在这里,我们可以简单地使用type()方法来生成python类。这可以在以后通过将它们添加到locals()内置函数来创建具有自己名称的对象。你知道吗

下面举一个例子

classes = ["Class1", "Class2"]

class_fileds = [
    {
        'cl1_var1': "test",
        'cl1_var2': 123,
    },
    {
        'cl2_var1': [1, 2, 3],
    }
]

classes_details = list(zip(classes, class_fileds))  # Python3 format

for class_details in classes_details:
    class_name = class_details[0]
    class_attrs = class_details[1]
    class_def = type(
            class_name,
            (object, ), # Base classes tuple
            class_attrs
        )
    locals().update({class_name: class_def})  # To associate the class with the script running

instance1 = Class1()
instance2 = Class2()

输出

>>> instance1 = Class1()
>>> instance2 = Class2()
>>>
>>> instance1.cl1_var1
'test'
>>> instance1.cl1_var2
123
>>> instance2.cl2_var1
[1, 2, 3]

在这里,列表中的类名classes=[“Class1”,“Class2”],可以按给定的方式使用,即Class1(),Class2()等。这是通过使用local()内置函数将变量Class1和Class2动态添加到运行脚本来实现的

2。专门创建动态django模型

尽管基本逻辑保持不变,但仍需要进行一些更改。你知道吗

首先,我们需要了解Django中的动态模型创建。Django为此提供了清晰的文档。你知道吗

请参阅https://code.djangoproject.com/wiki/DynamicModels

下面可以看到一个例子,您可以直接将下面的脚本添加到型号.py文件

from django.db import models
from django.db.models import CharField, IntegerField

# This is taken from https://code.djangoproject.com/wiki/DynamicModels#Ageneral-purposeapproach
def create_model(name, fields=None, app_label='', module='', options=None, admin_opts=None):
    class Meta:
        pass

    if app_label:
        setattr(Meta, 'app_label', app_label)

    if options is not None:
        for key, value in options.iteritems():
            setattr(Meta, key, value)
    attrs = {'__module__': module, 'Meta': Meta}  # Set up a dictionary to simulate declarations within a class

    if fields: # Add in any fields that were provided
        attrs.update(fields)
    model = type(name, (models.Model,), attrs)  # Create the class, which automatically triggers ModelBase processing

    return model


classes = ["Class1", "Class2"]

class_fileds = [
    {
        'cl1_var1': CharField(max_length=255),
        'cl1_var2': IntegerField(),
    },
    {
        'cl2_var2': IntegerField(),
    }
]

models_details = list(zip(classes, class_fileds))

for model_detail in models_details:
    model_name = model_detail[0]
    model_attrs = model_detail[1]

    model_def = create_model(
        model_name,
        fields=model_attrs,
        app_label=__package__,
        module= __name__,
    )

    locals()[model_name] = model_def

django shell的输出

>>> from my_app.models import Class1
>>> Class1(cl1_var1="Able to create dynamic class", cl1_var2=12345).save()
>>> Class1.objects.all().values()
<QuerySet [{'cl1_var1': 'Able to create dynamic class', 'id': 3, 'cl1_var2': 12345}]>

这个模型被添加到django应用程序中,我的应用程序这将很好地工作,并且有一些事情需要注意

  1. 在从文本文件中读取字段属性时,应该小心处理字段属性
  2. 应该使用locals()从应用程序导入模型
  3. 方法,create\u model应该取自参考链接,因为它支持添加管理页面等更多功能
  4. 数据迁移也适用于这种模型

我的建议

上面解释的方法不会有任何问题,它们都是受支持的,但有一点不能忘记,动态导入的类和实际导入的类之间存在性能差异。此外,这是一个有点复杂的结构和任何代码中的变化,应该非常小心地做,以不打破它。你知道吗

所以我的建议是读取带有配置的文本文件并生成型号.py使用一些魔术脚本(也可以在python中创建)从配置文件中删除文件。 因此,每次文本配置文件发生更改时,都必须生成型号.py脚本。这样还可以确保模型定义

相关问题 更多 >