跳过odoo中的继承顺序调用
Skip inheritance order call in odoo
我有一个 class 继承自 project.task,名为 ProjectTask
class 有一个复制方法覆盖了 project.task 的 复制函数 它被命名为 Task
我需要 运行 我的 class 中的基本复制函数,而不是 parents class
中的一个
这是我的 class 代码:
@api.multi
@api.returns('self', lambda value: value.id)
def copy(self, default=None):
if default is None:
default = {}
if not default.get('name'):
default['name'] = self.name.id
return super(ProjectTask, self).copy(default) #<-- I don't want to call the inherited class method I want to call the base class method instead
这是从基础复制的方法class(任务)
@api.multi
@api.returns('self', lambda value: value.id)
def copy(self, default=None):
if default is None:
default = {}
if not default.get('name'):
default['name'] = _("%s (copy)") % self.name
return super(Task, self).copy(default) # <-- I want to run this method from my class (ProjectTask) which is the child class
我们非常欢迎任何建议
使用你展示的 parent class 实现,用你自己的 default
调用它应该做你想做的,因为它只会将它传递给它自己的 parent 没有变化。 (至少,对于裸方法代码来说是这样,我不知道 odoo 装饰器做了什么来改变东西。)
但如果您确实出于某些 non-obvious 原因确实需要跳过它,您可能可以做到。一般来说,如果您不希望您的 class 用于多重继承,这些方法只会按预期工作。如果您的 MRO 变得复杂,那么您 真的 想用 super
做正常的事情,并使您的所有方法很好地协同工作。
跳过继承方法的一个选项是直接命名您希望呼叫转到的 class(即您的 grandparent class)。
class Base():
def foo(self):
print("Base")
class Parent(Base):
def foo(self):
print("Parent")
super().foo() # super() in Python 3 is equivalent to super(Parent, self)
class Child(Parent):
def foo(self):
print("Child")
Base.foo(self) # call Base.foo directly, we need to pass the self argument ourselves
另一种选择是更改您给 super
的参数以命名 parent class 而不是您自己的 class。通常这是一个新手错误,但如果这真的是你想要的,它是允许的(尽管我强烈建议在代码中添加注释,解释你 确实 想要这种行为!
class Child(Parent):
def foo(self):
print("Child")
super(Parent, self).foo() # Note: Deliberately skipping over Parent.foo here!
最后一点:如果您发现自己想跳过 parent class 中某些方法的实现,也许您应该重新考虑是否真的应该继承它.可能您真的想从与它相同的基础 class 继承,并完全跳过中间的 class。显然,这有其自身的局限性(也许某些库代码会针对 class 进行类型检查),但如果您发现自己在与继承机制作斗争,则可能是您做事的方式很困难,并且有一个更简单的选择。
我有一个 class 继承自 project.task,名为 ProjectTask
class 有一个复制方法覆盖了 project.task 的 复制函数 它被命名为 Task
我需要 运行 我的 class 中的基本复制函数,而不是 parents class
中的一个这是我的 class 代码:
@api.multi
@api.returns('self', lambda value: value.id)
def copy(self, default=None):
if default is None:
default = {}
if not default.get('name'):
default['name'] = self.name.id
return super(ProjectTask, self).copy(default) #<-- I don't want to call the inherited class method I want to call the base class method instead
这是从基础复制的方法class(任务)
@api.multi
@api.returns('self', lambda value: value.id)
def copy(self, default=None):
if default is None:
default = {}
if not default.get('name'):
default['name'] = _("%s (copy)") % self.name
return super(Task, self).copy(default) # <-- I want to run this method from my class (ProjectTask) which is the child class
我们非常欢迎任何建议
使用你展示的 parent class 实现,用你自己的 default
调用它应该做你想做的,因为它只会将它传递给它自己的 parent 没有变化。 (至少,对于裸方法代码来说是这样,我不知道 odoo 装饰器做了什么来改变东西。)
但如果您确实出于某些 non-obvious 原因确实需要跳过它,您可能可以做到。一般来说,如果您不希望您的 class 用于多重继承,这些方法只会按预期工作。如果您的 MRO 变得复杂,那么您 真的 想用 super
做正常的事情,并使您的所有方法很好地协同工作。
跳过继承方法的一个选项是直接命名您希望呼叫转到的 class(即您的 grandparent class)。
class Base():
def foo(self):
print("Base")
class Parent(Base):
def foo(self):
print("Parent")
super().foo() # super() in Python 3 is equivalent to super(Parent, self)
class Child(Parent):
def foo(self):
print("Child")
Base.foo(self) # call Base.foo directly, we need to pass the self argument ourselves
另一种选择是更改您给 super
的参数以命名 parent class 而不是您自己的 class。通常这是一个新手错误,但如果这真的是你想要的,它是允许的(尽管我强烈建议在代码中添加注释,解释你 确实 想要这种行为!
class Child(Parent):
def foo(self):
print("Child")
super(Parent, self).foo() # Note: Deliberately skipping over Parent.foo here!
最后一点:如果您发现自己想跳过 parent class 中某些方法的实现,也许您应该重新考虑是否真的应该继承它.可能您真的想从与它相同的基础 class 继承,并完全跳过中间的 class。显然,这有其自身的局限性(也许某些库代码会针对 class 进行类型检查),但如果您发现自己在与继承机制作斗争,则可能是您做事的方式很困难,并且有一个更简单的选择。