简体   繁体   English

如何以编程方式在 Python 中创建 class 方法?

[英]How do I programmatically create class methods in Python?

Suppose I want to define a Python class whose instances have several members of similar form:假设我想定义一个 Python class 其实例有几个类似形式的成员:

class Bar:
    def __init__(self):
        self.baz=3
        self.x=1
        self.name=4

I can instead create all members at once using explicit manipulation of __dict__ :我可以使用__dict__的显式操作一次创建所有成员:

class Bar:
    def __init__(self):
        self.__dict__.update({name: len(name) for name in ("baz", "x", "name")})

However, if the associated members are class data members, instead of instance members, then I am aware of no analogous way to programmatically mutate Bar.__dict__ :但是,如果关联成员是class数据成员,而不是实例成员,那么我知道没有类似的方法来以编程方式改变Bar.__dict__

class Bar:
    #Fails with "AttributeError: 'mappingproxy' object has no attribute 'update'"
    Bar.__dict__.update({name: len(name) for name in ("baz", "x", "name")})

In Javascript, programmatically manipulating the properties of a constructor is possible, because constructors are just ordinary functions, which are just ordinary objects, and therefore just a mutable dictionary mapping properties to more objects.在 Javascript 中,以编程方式操作构造函数的属性是可能的,因为构造函数只是普通函数,它们只是普通对象,因此只是将属性映射到更多对象的可变字典。 Is it possible to write analogous code in Python?是否可以在 Python 中编写类似的代码?

I guess you can use a metaclass, a base class with __init_subclass__ or use eval to create your class. Here's an example using a base class:我猜你可以使用一个元类,一个基数 class 和__init_subclass__使用eval来创建你的 class。下面是一个使用基数 class 的例子:

class Base:
    attrs_to_set: set[str] = set()

    def __init_subclass__(cls) -> None:
        for attr in cls.attrs_to_set:
            setattr(cls, attr, cls.get_attr_value(attr))

    @classmethod
    def get_attr_value(cls, attr_name: str):
        # default, you can change it depending on your use case i guess.
        return len(attr_name)


class Bar(Base):
    attrs_to_set = {"x", "baz", "name"}


print(Bar.x, Bar.name, Bar.baz)
# prints: 1 4 3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM