在Python中以动态字符串的形式创建一个给定类名的对象

2024-06-16 10:51:05 发布

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

假设我有两门课:

你知道吗表格.py你知道吗

class Device79table(tables.Table):
    class Meta:
        #link to datasource
        model = Device79
        attrs = {"class": "paleblue"} 

你知道吗型号.py你知道吗

class Device79(models.Model):
    # data for table  

我有一个引用这两个类的函数。你知道吗

你知道吗视图.py你知道吗

def function():
    #makes table of all objects in device 79
    table = Device79table(Device79.objects.all()) 
    table.draw() 

有可能这样做吗?假设参数“device”=Device79

def function(device)
    table = device+table(device.objects.all())
    table.draw() 

这样就可以根据设备的值来绘制表格。即设备可以是设备79、设备80、设备81等。。程序会自动绘制正确的表格。你知道吗


Tags: pytablesobjectsdevicedeftable绘制function
3条回答

更新

这是一个新的解决方案,它考虑到了这样一个事实:您实际上并没有实例化类,而是直接使用类对象。你知道吗

因为Device79必须在Device79table.Meta之前定义,所以不能告诉Device79在它自己的定义中使用哪个表。你甚至不能在Device79table期间这样做,因为它还不存在。你知道吗

因此,您需要在定义相应的表之后告诉Device79使用哪个表。你知道吗

如您所见,我也选择不使用动态变量名,而是在其他变量中使用一个明确定义的对象。动态变量名使代码更难阅读和维护。你知道吗

型号.py

class Device79(models.Model):
    table = None  # Optional, but cleaner.

表格.py

import models

class Device79table(tables.Table):
    class Meta:
        # link to datasource
        model = models.Device79
        attrs = {"class": "paleblue"} 

# once the table is defined, we can tell Device79 which table to use.
models.Device79.table = Device79table

视图.py

import tables  # "from tables import Device79table" would work too.
from models import Device79
# You need to import tables, even if you access the tables from the models,
# because this is where we tell the device which table to use.

def function(device)
    table = device.table(device.objects.all())
    table.draw() 

function(Device79)

通常,循环导入不是问题,只要您导入模块而不是单个对象,但是由于您需要在定义表的过程中直接访问模型,因此无法在models.py中导入表。这就是为什么我们改变tables.py中的设备来告诉它使用哪个表,而不是直接在models.py中设置它。你知道吗

这样,我们保持导入链如下:views -> tables -> modelsmodels从不尝试导入tables,但这也意味着我们必须至少在某处导入tables一次才能完成模型定义。你知道吗

这有点令人惊讶,但我想不出一个更干净更简单的方法来做这件事,而只处理类对象,而不是实例。你知道吗

我不知道Device79table是在哪里定义的,但我假设它是global

我的假定义是:

def Device79Table(arg):
    print arg

将其与您的功能结合起来:

def function(device):
    globals()[device + 'table'](device.objects.all())
    table.draw()

globals()函数返回所有全局对象的dict,其中键是它们名称的字符串。所以globals()['Device79table']Device79table是一样的

Python在反射方面尤其出色。根据您的描述,以下是您可以做的示例:

models.py中:

class Device79:
    objects = "Device79.objects"

tables.py中:

class Device79table:
    def __init__(self, devices):
        self.devices = devices

    def draw(self):
        print "%s.draw() called with %s" % (self.__class__, self.devices)

然后在views.py

import tables

def function(device):
    table = tables.__dict__[device.__name__ + 'table'](device.objects)
    table.draw()

import models
function(models.Device79)

或者:

from models import Device79
function(Device79)

相关问题 更多 >