如何从python中的给定文本创建一组类及其var和方法 [英] how to create a set of classes and its vars and methods from a given text in python

查看:84
本文介绍了如何从python中的给定文本创建一组类及其var和方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想仅通过给定的文本配置(尤其是django模型)创建一组类,其vars和methodes,例如,我在model.py中创建了一系列模型。py

I want to create a set of classes, its vars and methodes just from a given text configuration, espcially with django models, for exmaple i have a list of models to create in models.py

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

在models.py
i中想要创建类似的东西来创建该类

in models.py i want to make something like this to create that classes

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

我如何编程#create_classes_from_string以确保它使用该配置在数据库中创建表

how can i program #create_classes_from_string assuring that it creates tables in my database with that configuration

推荐答案

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

I can view this question in 2 perspectives


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

  2. 专门创建动态django模型

但是在两种情况下,attr都应为defi带有变量名称及其值的dict。因为在这里定义没有值的变量是没有意义的。

But in both cases, the attrs should be defined as dict with the variable name and its value. Because defining a variable without a value is meaningless here.

在这里,我们可以简单地使用 type()方法来生成python类。以后可以将其添加到内置函数locals()中,从而使用自己的名称创建对象。

Here we can simply use type() method to generate a python class. This can be later used to create object with their own name by adding them to locals() builtin function.

下面提到一个示例

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添加到运行脚本来实现的)内置函数

Here the class names in the list, classes = ["Class1", "Class2"], can be used as such as given i.e. Class1(), Class2() etc. This is achieved by adding the variables Class1 and Class2 to the running script dynamically by using local() inbuilt function

即使基本逻辑保持不变,也需要进行一些更改。

Even though the basic logic remains the same there are a couple of changes required.

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

First of all we need to understand the dynamic model creations in Django. Django provides a clear documentation for this.

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

示例如下,您可以将以下脚本直接添加到models.py文件中

An example can be seen as below, you can directly add the below script to models.py file

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的输出

Output at 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应用 my_app 中,并且可以正常工作,并且有一个需要注意的几件事

This model is added to django app, my_app and this would work fine and there are a few things to be noted


  1. 字段属性应谨慎处理,因为您将从文本文件中读取内容

  2. 应该使用locals()添加模型以从应用程序导入模型

  3. 方法,应该从参考链接中获取create_model,因为它支持更多功能,例如添加管理页面等。

  4. 数据迁移也可以使用这种模型

  1. field attrs should be handled carefully as you are going to read that from text file
  2. The models should be added using locals() to import that from app
  3. Method, create_model should be taken from the reference link as it supports more features like adding admin pages etc
  4. Data migration also works with this kind of model


我的建议


以上-解释的方法可以正常工作,并且所有方法都受支持,但不可忘记的是,动态导入的类和实际导入的类之间存在性能差异。同样,这是一个有点复杂的结构,对代码的任何更改都应该非常小心地进行,以免将其破坏。

My Suggestion

The above-explained methods would work without any issue and all of them are supported but one thing to be not forgotten that, there is performance difference in dynamically imported classes and real import. Also, this is a bit complex structure and any change in the code should be done very carefully to not break it up.

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

So my suggestion is to read the text file with configurations and generate models.py file from the configuration file using some magic script(that can also be created in python). So every time there is a change in the text-config file you have to generate the models.py script. This way you can also ensure the Model definitions

这篇关于如何从python中的给定文本创建一组类及其var和方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆