2

想象一个像数据库表信息(表名和列)容器一样工作的类。

这是一个实现。

class TABLES(Enum):

    class TABLE1: 
        """ documentation for first table """
        NAME = "My First Table"
        COL11 = "col11"
        COL12 = "col12"
        COL13 = "col13"

    class TABLE2: 
        """ documentation for second table """
        NAME = "My Second table"
        COL21 = "col21"
        COL22 = "col22"
        COL23 = "col23"

我的目标是在不显式调用属性的情况下访问枚举的值(即类TABLE1或)。TABLE2value

因此,例如,如果我想连接我想写的第一个表的前两列

TABLES.TABLE1.COL1 + TABLES.TABLE1.COL2

代替

TABLES.TABLE1.value.COL1 + TABLES.TABLE1.value.COL2

我不需要类TABLES是枚举,但我有两个要求:

  • TABLES需要可迭代
  • 一旦我写了,我想看看所有的表选择TABLES.

此外,我需要将单个表作为类,因为我想在每个表上添加一个小文档。

4

2 回答 2

1

您可以将 anamedtuple用于外部Tables类,将普通类用于实际的表定义:

from collections import namedtuple

class Table: pass

class Table1(Table): 
    """ documentation for first table """
    NAME = "My First Table"
    COL11 = "col11"
    COL12 = "col12"
    COL13 = "col13"

class Table2(Table): 
    """ documentation for second table """
    NAME = "My Second table"
    COL21 = "col21"
    COL22 = "col22"
    COL23 = "col23"

Tables = namedtuple("Tables", (t.__name__ for t in Table.__subclasses__()))
TABLES = Tables(*Table.__subclasses__())

这允许写入TABLES.Table1.COL11,也允许迭代TABLES
继承,__subclasses__仅用于将表类自动添加到命名元组。

一个不同的解决方案是在您自己的代码中添加一个方法,列出表格:

class Tables:
    class Table1: 
        """ documentation for first table """
        NAME = "My First Table"
        COL11 = "col11"
        COL12 = "col12"
        COL13 = "col13"

    class Table2: 
        """ documentation for second table """
        NAME = "My Second table"
        COL21 = "col21"
        COL22 = "col22"
        COL23 = "col23"

    def list_tables():
        return (var for name, var in vars(Tables).items()
                if not name.startswith("__") and type(var) == type)

这也应该允许写入Tables.获取表列表(尽管这取决于您的 IDE 的功能)。

于 2022-02-01T09:53:20.263 回答
0

如果你只需要你的类是可迭代的,你可以使用一个使用元类。通过继承来注册您的嵌套类以参与迭代.Value

class BagOfClass(type):
    class Value:
        pass

    def __iter__(klass):
        for attr_value in vars(klass).values():
            if isinstance(attr_value, type) and issubclass(
                attr_value, BagOfClass.Value
            ):
                yield attr_value


class Tables(metaclass=BagOfClass):
    class Table1(BagOfClass.Value):
        """documentation for first table"""

        NAME: str = "My First Table"
        COL11: str = "col11"
        COL12: str = "col12"
        COL13: str = "col13"

    class Table2(BagOfClass.Value):
        """documentation for second table"""

        NAME: str = "My Second table"
        COL21: str = "col21"
        COL22: str = "col22"
        COL23: str = "col23"


print(*[table.NAME for table in Tables])
于 2022-02-01T10:29:09.740 回答