创建具有任意替换属性名的Python类

0 投票
4 回答
1028 浏览
提问于 2025-04-16 11:37

抱歉我没有给这个问题起个更好的标题;我发这个问题是因为我连正确的术语都不知道该用什么。

我定义了一个类,里面有一个属性叫做'spam':

def SpamClass(object):
    def __init__(self, arg):
        self.spam = arg
    def __str__(self):
        return self.spam

我想创建一个(子类/兄弟类?)功能完全相同的类,但属性名换成'eggs',而不是'spam':

def EggsClass(object):
    def __init__(self, arg):
        self.eggs = arg
    def __str__(self):
        return self.eggs

总的来说,我该如何创建功能相同但属性名可以随意命名的类呢?当类的行为比较复杂时,重复代码似乎很傻。

更新:我同意这听起来像是设计不佳。为了澄清,我并不是想用这种愚蠢的方式解决某个特定问题。我只是想知道如何在不影响功能的情况下,随意命名一个对象的 __dict__ 内容。想想像 keys() 这样的方法,适用于像 dict 的对象。人们创建各种类,并且这些类的 keys() 方法按照约定的方式工作,这种命名约定是件好事。但这个名字是可以随意选择的。我该如何创建一个 spam() 方法,完全替代 keys(),而不需要在源代码中手动替换 /keys/spam/ 呢?

我觉得重载 __getattr__ 之类的方法来引用通用属性显得不够优雅,而且不够稳定。如果一个子类重新实现了这些方法,它必须适应这种行为。我更希望用户看到的只是一个基础类,里面有一个可以直接访问的命名属性。

实际上,我能想到一个合理的使用场景。假设你想要一个混入类,它提供一个特殊属性和一些与这个属性相关的方法,这些方法可以操作或依赖于这个属性。用户可能希望为不同的类命名这个特殊属性,以便与现实问题领域中的名称匹配,或者避免名称冲突,同时又能重用底层的行为。

4 个回答

1

你可以先创建一个超级类,把所有共同的内容放在里面,然后再创建一些子类,给它们添加特定的属性。

或者你也可以这样做:

def SuperClass(object):
    specific_attribute = 'unset'

    def __init__(self, arg):
        setattr(self, specific_attribute, arg)

    def __str__(self):
        return getattr(self, specific_attribute)


def EggClass(SuperClass):
    specific_attribute = 'eggs'
1

你有没有想过不要把事情搞得太复杂,干脆只创建一个类呢?(因为它们其实是一样的)

class FoodClass(object):
    def __init__(self, foodname, arg):
        self.attrs = {foodname: arg}
        self.foodname = foodname

    def __str__(self):
        return self.attrs[foodname]

如果你想要一些好用的构造函数,可以单独创建它们:

def make_eggs(arg):
    return FoodClass('eggs', arg)

def make_spam(arg):
    return FoodClass('spam', arg)
4

这里有一种方法可以实现你想要的效果。

首先,定义一个通用的类,并给它一个通用的属性名称。然后在每个子类中,按照这个链接里的建议,来让这个属性在外部看起来像是你想要的名字。

你描述的做法让我觉得有点问题,我建议你仔细审视一下自己的设计,看看这是否真的是你想要的。不过,你可以按照我的建议来实现它。

撰写回答