动态更改类的一个方法

2024-04-26 12:59:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我的问题是双重的。 首先,我想定义一个类,它有一个方法scale,该方法的行为取决于分配给它的一个属性的值。 下面是我当前尝试的XXX签名代码中缺少某些内容的部分。你知道吗

class C(object):
    def __init__(self):
        self._scaling_method = None

    def same(self, u):
        return u

    def double(self, u):
        return u * 2

    scale = same

    @property
    def scaling_method(self):
        return self._scaling_method

    @scaling_method.setter
    def scaling_method(self, value):
        if value.lower() == "double":
            self._scaling_method = "double"
            print "Scaling method set to 'double'."
            # XXX method scale should be set to double
        elif value.lower() == "same":
            self._scaling_method = "same"
            print "Scaling method set to 'same'."
            # XXX method scale should be set to same
        else:
            print "Unknown scaling method."

如果cC的一个实例,我希望能够

c.same(3) # yields 3
c.double(3) # yields 6
c.scale(3) # yields 3 because scale defaults to same
c.scaling_method = "double"
c.scale(3) # yields 6

正确设置后,我希望能够使用参数设置scaling_method属性,并在__init__中相应地定义scale方法。目前,我在第二部分看到的唯一解决方案是在类的核心和__init__部分中定义每个缩放方法,这看起来相当尴尬。你知道吗

编辑:我刚刚注意到this answer可能在这里被改编。你知道吗


Tags: to方法selfreturn定义initdefmethod
2条回答

如前所述,不清楚您是希望在类基础上还是在实例基础上执行。 下面是一个基于实例的解决方案。我用比例尺法:

class C(object):
    def __init__(self):
        self._scaling_method = None

    def same(self, u):
        return u

    def double(self, u):
        return u * 2

    scale = same

    @property
    def scaling_method(self):
        return self._scaling_method

    @scaling_method.setter
    def scaling_method(self, value):
        if value.lower() == "double":
            self._scaling_method = "double"
            self.scale = self.double
        elif value.lower() == "same":
            self._scaling_method = "same"
            self.scale = self.same
        else:
            print "Unknown scaling method."

如果您想在类的基础上使用它,请将self.scale = ...替换为 self.__class__.scale = ...。注意:这可能被认为是黑客行为 因为我真的在改变课程。你知道吗

那么

sage: c = C()
sage: c.scale(3)
3
sage: c.scaling_method = "double"
sage: c.scale(3)
6

请注意,该类的其他对象不受影响:

sage: cc = C()
sage: cc.scale(4)
8

如果希望在类的基础上具有相同的行为:

class C(object):
    _scaling_method = None

    def same(self, u):
        return u

    def double(self, u):
        return u * 2

    scale = same

    @property
    def scaling_method(self):
        return self._scaling_method

    @scaling_method.setter
    def scaling_method(self, value):
        if value.lower() == "double":
            self.__class__._scaling_method = "double"
            self.__class__.scale = self.double
        elif value.lower() == "same":
            self.__class___.scaling_method = "same"
            self.__class__.scale = self.same
        else:
            print "Unknown scaling method."

然后像前面的代码一样:

sage: c = C(); cc = C()
sage: c.scale(2), cc.scale(3)
(2, 3)
sage: c.scaling_method = "double"
sage: c.scale(2)
4

但现在cc也受到了影响:

sage: cc.scale(3)
6

这是我从this answer得到的一个解。print语句可以替换为正确的错误处理。你知道吗

class C(object):
    def __init__(self, scaling_method="same"):
        self._list_scaling_methods = ("same", "double")
        if scaling_method in self._list_scaling_methods:
            self._scaling_method = scaling_method
        else:
            print "Unknown scaling method."
            self._scaling_method = None

    @property
    def scaling_method(self):
        return self._scaling_method

    @scaling_method.setter
    def scaling_method(self, value):
        if value in self._list_scaling_methods:
            self._scaling_method = value
        else:
            print "Unknown scaling method."

    @property
    def scale(self):
        return getattr(self, self._scaling_method)

    def same(self, u):
        return u

    def double(self, u):
        return u * 2

相关问题 更多 >