如何在python中继承class(odoo框架控制器)

How to inherit class in python (odoo framework controller)

我在 Python 中遇到了继承问题。我希望程序的输出是:

# url: home/animal
response: CLASS: Animal | Ability : none

# url: home/animal/bird
response: CLASS: Bird | Ability : Fly

# url: home/animal/fish
response: CLASS: Fish | Ability : Swim

但我得到以下输出:

# url: home/animal
response: CLASS: Fish | Ability : Swim

# url: home/animal/bird
response: CLASS: Fish | Ability : Swim

# url: home/animal/fish
response: CLASS: Fish | Ability : Swim

这是我的代码:

class Animal(http.Controller):
    name = 'Animal'
    ability = 'none'

    @http.route('/animal', auth='public', type='http', website=True, csrf=False)
    def util(self, **kwargs):
        return self.message()

    def message(self):
        return "Name: "+self.name +" | Ability : " + self.ability

class Bird(Animal):
    name = 'Bird'
    ability = 'fly'

    @http.route('/animal/bird', auth='public', type='http', website=True, csrf=False)
    def util1(self, **kwargs):
        return self.message()


class Fish(Animal):
    name = 'Fish'
    ability = 'swim'

    @http.route('/animal/fish', auth='public', type='http', website=True, csrf=False)
    def util2(self, **kwargs):
        return self.message()

我已经阅读了很多关于继承的内容,但仍然找不到解决这个问题的方法。 难道是因为它在odoo中有不同的系统python?

编辑: 这是基于@Bruno 的回答的有效代码。

class Animal():
    name = 'Animal'
    ability = 'none'

    def message(self):
        return "Name: {self.name} | Ability : {self.ability} ".format(self=self)

class Bird(Animal):
    name = 'Bird'
    ability = 'fly'

class Fish(Animal):
    name = 'Fish'
    ability = 'swim'

class MyController(http.Controller):
    def __init__(self):
        self._animal = Animal()
        self._bird = Bird()
        self._fish = Fish()

    @http.route('/animal', auth='public', type='http', website=True, csrf=False)
    def animal(self, **kwargs):
        return self._animal.message()

    @http.route('/animal/bird', auth='public', type='http', website=True, csrf=False)
    def bird(self, **kwargs):
        return self._bird.message()

    @http.route('/animal/fish', auth='public', type='http', website=True, csrf=False)
    def fish(self, **kwargs):
        return self._fish.message()

你真的想继承http.controller吗?如果是这样,Odoo 中的默认 0Auth 模块也许可以向您展示它是如何排列的(因为它也继承了这个 class)。

如果您只是想向 Odoo 添加一个新的 class,请注意它有自己的继承系统,这在文档中有描述(并且工作方式与默认 python 有很大不同) : Odoo inheritance documentation for version 11.0

请注意,虽然我没有在 Odoo 中继承 Odoo 对象以外的任何东西的个人经验,但我在标准插件中发现了很多示例,它们应该对您有所帮助。

警告:我从来没有使用过 odoo,所以这个答案部分是根据我从文档中得到的内容和您描述的行为进行的随意猜测。

According to the doc,看起来从控制器继承实际上会覆盖原始控制器,而不是添加一个新控制器(注意,请参阅上面的警告,好吗?)。如果是这样,您可以尝试的一件事是改用多重继承,将您的特定功能提取到非控制器基础 class:

class Animal(object):
    name = 'Animal'
    ability = 'none'

    def message(self):
        # using string formatting for improved readability
        return "Name: {self.name} | Ability : {self.ability}".format(self=self)


class Bird(Animal):
    name = "Bird"
    ability = Fly

# etc

class AnimalController(Animal, http.Controller):
    @http.route('/animal', auth='public', type='http', website=True, csrf=False)
    def util(self, **kwargs):
        return self.message()

class BirdController(Bird, http.Controller):
    @http.route('/animal/bird', auth='public', type='http', website=True, csrf=False)
    def util(self, **kwargs):
        return self.message()

但这在我看来并不是一个好的设计。控制器通常可以处理许多路由(所有 MVC Web 框架都是这种情况,并且由于 route 装饰器将应用于方法,我假设这在这里工作相同),所以只保留可能更简单一个控制器并委托给您的 Animal 层次结构:

class Animal(object):
    name = 'Animal'
    ability = 'none'

    def message(self):
        # using string formatting for improved readability
        return "Name: {self.name} | Ability : {self.ability}".format(self=self)


class Bird(Animal):
    name = "Bird"
    ability = Fly

# etc


class Controller(http.controller):
    def __init__(self, ...):
        self._animal = Animal()
        self._bird = Bird()
        # etc

    @http.route('/animal', auth='public', type='http', website=True, csrf=False)
    def animal(self, **kwargs):
        return self._animal.message()

    @http.route('/animal/bird', auth='public', type='http', website=True, csrf=False)
    def bird(self, **kwargs):
        return self._bird.message()

   # etc

这当然是不完整的示例代码,因此您了解了总体思路,显然需要进行修改以符合 odoo 的期望和您的项目需求。