【问题标题】:Correct way to have the same method defined differently between instances在实例之间以不同方式定义相同方法的正确方法
【发布时间】:2020-02-26 23:49:36
【问题描述】:

我正在尝试在 Python 中创建一个类,其方法在不同实例之间的定义不同(使用相同的名称)。不同的定义可以基于创建实例时类的输入。

例如:

Class A:
     def __init__(self, a):
         ...

     def foo(self):
         ...

a1 = A(input1)
a2 = A(input2)
a1.foo()
a2.foo()

我希望为这两个实例定义不同的 foo()。我可以将此逻辑编码到foo 方法中,但想知道是否有更简洁或更Pythonic 的方式来执行此操作。 谢谢。

【问题讨论】:

  • 你想用这种有问题的技术来完成什么?
  • 你的例子没有任何帮助。
  • 我有一个对象渲染方法,它在各种对象(实例)之间的工作方式完全不同。我没有创建一个检查实例并应用特定渲染逻辑的复杂方法,而是很好奇这是否可以通过基于实例本身的同一方法的多个定义来完成。
  • 如果每个实例的代码不同,则在创建实例时将其作为回调传递可能是有意义的。 A(a, some_function)

标签: python class methods instance


【解决方案1】:

我希望 foo() 为这两个实例定义不同的

你真的不想这样。我无法想象这会导致调试噩梦。

如果a1.fooa2.foo 不同,则意味着a1a2 不应是同一类的实例

使用子类并酌情在每个类中实现foo

Class Common:
    # common stuff
    ...

Class A1(Common):
    def foo(self):
        print('a1.foo')

Class A2(Common):
    def foo(self):
        print('a2.foo')

a1 = A1()
a2 = A2()
a1.foo()
# 'a1.foo'
a2.foo()
# 'a2.foo'

【讨论】:

  • 在我的情况下,将其分离为子类有点混乱,但似乎是正确的解决方案。记下了,谢谢。
  • @bdemin 它一点也不凌乱,尤其是与其他替代品相比时。
  • 这是一个很好的解决方案,如果将它与factory 方法结合使用,它可能完全符合您的要求。您将input1input2 传递给Common.__init__(),它将根据此输入返回A1 或A2 对象。然后,您可以像使用它们一样使用它们,因为它们具有相同的接口。
  • 这对我的问题来说是一个很好的解决方案。谢谢@mattrea6!
【解决方案2】:

不能这样做。但您始终可以随时为对象添加自定义属性。

class A:
    def __init__(self, x):
        self.x = x

a1 = A()
a2 = A()

def foo1():
    # you can't use self.x
    print("a1")

a1.foo = foo1
a2.foo = lambda : print("a2")

a1.foo() # a1
a2.foo() # a2

但这不是一个好的做法,使用它需要您自担风险。

此外,正如 cmets 中所指出的,您无权访问实例属性(因为没有隐式 self 参数)。

【讨论】:

  • 仅仅因为你可以做一件事并不意味着你应该
  • 不知道我可以即时向实例添加方法。谢谢。
  • 您将如何从 lambda 访问实例属性?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-01
  • 2016-05-01
  • 2013-03-05
  • 1970-01-01
相关资源
最近更新 更多