簡體   English   中英

如何使用初始化程序在Python中動態創建類

[英]How to dynamically create a class in Python with an initializer

這是一些開始的代碼:

def objectify(name, fields):
    """ Create a new object including the __init__() method. """
    def __init__(self, *argv):
        for name, val in zip(var_names, argv):
            setattr(self, name, val)

    # The following line of code is currently limited to a single dynamic class.
    # We would like to extend it to allow creating multiple classes
    # and each class should remember it's own fields.
    __init__.var_names = fields

    result = type(name, (object,), dict(__init__=__init__))

這里的挑戰是找到一種方法來為每個類的__init__()方法制作唯一的副本,該方法具有其變量名的靜態列表。

計划B:我們可以使用eval()來運行函數生成的代碼。 但是應盡可能避免使用eval() 這里的挑戰是在沒有eval()情況下執行此操作。

編輯:在撰寫問題時,我想出了一個解決方案。 (請參閱下文。)也許這會對某人有所幫助。

EDIT2:我將使用此函數來創建諸如namedtuple()類的東西,只是它們是可變的。

Point = objectify('point', ['x', 'y'])
a = Point(1, 2)
b = Point(2, 3)
print a.__dict__
print b.__dict__

稍后您將不提及任何有關字段用法的信息。 如果只在__init__需要它們,則根本不需要保存它們:

def objectify(name, fields):
    """ Create a new object including the __init__() method. """
    fields = fields[:]
    def __init__(self, *argv):
        for name, val in zip(fields, argv):
            setattr(self, name, val)

    result = type(name, (object,), dict(__init__=__init__))
    return result

否則,您應該查看元類-正是它們的用例。

更新:復制fields可確保在調用方中更改列表不會影響已存儲的列表。 值仍然可以更改...作為練習供讀者驗證所有內容是否為str

這是一種解決方案:

def objectify(obj_name, fields):
    """ Create a new object including the __init__() method. """

    def __init__(self, *argv):
        """ Generic initializer for dynamically created classes. """
        fields = objectify.fields[self.__class__.__name__]
        for field, val in zip(fields, argv):
            setattr(self, field, val)

    result = type(obj_name, (object,), dict())
    result.__init__ = __init__

    # Save the list of fields in a static dictionary that is retrieved by class name.
    objectify.fields[obj_name] = fields

    return result

objectify.fields = {}           # A static local variable.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM