0

我很抱歉没有给这个问题一个更好的标题;我发布它的原因是我什至没有正确的术语来知道我在寻找什么。

我已经定义了一个具有“垃圾邮件”属性的类:

def SpamClass(对象):
    def __init__(self, arg):
        self.spam = arg
    def __str__(self):
        返回 self.spam

我想创建一个(子/兄弟?)类,它具有完全相同的功能,但具有名为“eggs”而不是“spam”的属性:

def EggsClass(对象):
    def __init__(self, arg):
        self.eggs = arg
    def __str__(self):
        返回self.eggs

概括地说,如何创建具有任意属性名称的功能相同的类?当类具有复杂的行为时,重复代码似乎很愚蠢。

更新:我同意这闻起来像是糟糕的设计。澄清一下,我并不是想以这种愚蠢的方式解决特定问题。我只想知道如何__dict__在保留功能的同时任意命名对象的(非魔法)内容。考虑类似对象的keys()方法dict。人们使用符合约定的方法创建各种类,keys()命名约定是一件好事。但是这个名字是随意的。如何在不手动替换源中的 /keys/spam/ 的情况下使用spam()完全替换的方法创建一个类?keys()

重载__getattr__和朋友引用泛型属性对我来说似乎不优雅和脆弱。如果子类重新实现这些方法,它必须适应这种行为。我宁愿让用户觉得只有一个带有命名属性的基类,可以天真地访问。

实际上,我可以想到一个合理的用例。假设您想要一个具有特殊属性的 mixin 类和一些密切相关的方法来操作或依赖于该属性。用户可能希望在重用底层行为的同时,为不同的类以不同的方式命名这个特殊属性(以匹配实际问题域中的名称或避免名称冲突)。

4

4 回答 4

4

这是一种获得我认为你想要的效果的方法。

定义具有通用属性名称的通用类。然后在每个子类中遵循http://docs.python.org/reference/datamodel.html#customizing-attribute-access中的建议,使该属性在外部看起来就像它被称为任何您想要的名称一样。

你对你所做的事情的描述让我觉得它有一种“代码味道”,我建议非常仔细地审查你的设计,看看这是否真的是你想要做的。但是你可以按照我的建议让它工作。

于 2011-02-11T07:32:18.887 回答
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'
于 2011-02-11T07:50:05.317 回答
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)
于 2011-02-11T08:46:27.010 回答
0

要在运行时创建属性,只需将它们添加到self.__dict__['foo'] = 'I'm foo'类代码中。

于 2011-02-11T08:52:31.393 回答