根据实例变量为类实例提供不同的方法

时间:2014-03-06 18:39:13

标签: python class

我想创建一个类,其中实例具有不同的方法,具体取决于它们的变量。

例如:

class Spam:
    def __init__(self, eggs):
        self.eggs = eggs

然后,如果Spam的{​​{1}}为5,那么它应该self.eggs定义如下:

foo

,否则

def foo(self):
    print(self.eggs)

目前,我这样做是通过在类外声明def foo(self, excited): if excited: print("{}!!!!!".format(self.eggs)) else: print("{}...".format(self.eggs)) 个函数(具有不同的名称),并在foo中设置实例具有哪个函数作为方法。但是,这会从类定义中删除函数定义,我真的不想这样做。还有其他方法吗?

编辑:实际情境。

我正在制作一些类来表示图形中的节点,其中每个图形都可以加权或不加权。 我希望节点有一个__init__方法,将另一个节点作为参数,将它们连接在一起。加权图中的节点(即linkself.graph.weighted的节点)应具有True方法,其中另一个参数指定连接边的权重。有没有更好的方法呢?例如,使权重参数可选,但存在于所有节点的link方法中。

3 个答案:

答案 0 :(得分:1)

您可以foo只使用Spam的一种方法,默认参数为excited

In [49]: class Spam:
    ...:    def __init__(self, eggs):
    ...:        self.eggs = eggs
    ...: 
    ...:    def foo(self, excited=False):
    ...:        if self.eggs == 5:
    ...:            print(self.eggs)
    ...:            return
    ...: 
    ...:        if excited:
    ...:           print("{}!!!!!".format(self.eggs))
    ...:        else:
    ...:           print("{}...".format(self.eggs))

In [50]: Spam(5).foo()
5

In [51]: Spam(6).foo()
6...

In [52]: Spam(6).foo(True)
6!!!!!

答案 1 :(得分:1)

扩展jme提到的内容:

默认参数方法:

class Node:
    def __init__(self, name):
        self.name = name
        self.links = []

    def link(self, other, weight = None):
        self.links.append((other, weight))

继承方法:

class Node:
    def __init__(self, name):
        self.name = name
        self.links = []

    def link(self, other):
        #one of the following, depending if other methods of this base class will be used in the derived class
        self.links.append((other, None))
        #self.links.append(other)

class WeightedNode(Node):
    def link(self, other, weight):
        self.links.append((other, weight))

答案 2 :(得分:1)

这是您需要利用“工厂模式”的地方。也就是说,您需要有N个类(并非所有继承相关但与鸭类型相关),以便:

 def create_my_class(arg1, arg2, arg3=None, arg4=None):
   #optional arguments? Ah ha!
   if arg3 is not None and arg4 is not None:
     return MyClass(arg1, arg2, arg3, arg4)
   elif arg3 is not None:
     return AnotherClass(arg1, arg3)
   else:
     return YetAnotherClass(arg1, arg2)

所以你要解耦每个类的实现,但不是它的构造。然后,您可以使用(并替换)此方法来帮助创建不同的类。

   node1 = create_my_class(1, 1)
   node2 = create_my_class(1, 2, node1)
   node3 = create_my_class(1, 3, node1, 15)
   #etc...