首页 > 解决方案 > Python:如何在没有继承的情况下访问父类实例方法?

问题描述

具有抽象方法的基类_conn()

from cached_property import cached_property

class Base:
    
    def __init__(self, conn_id):
        """Store secrets details"""
        self.conn_id = conn_id
    
    @cached_property    
    def _conn(self):
        """Fetch secrets and generate authenticated client"""
        raise NotImplemented
    
    def get_conn(self):
        """Return authenticated client"""
        return self._conn

家长班

from cached_property import cached_property

class Parent(Base):

    @cached_property
    def _conn(self):
        """Generate authenticated client specific for Parent"""
        client = ...
        return client

儿童班

from typing import List, Optional
from pydantic.dataclasses import dataclass


@dataclass
class Toy:
    name: str
    type: str
    
    def get_color(self) -> str:
        color = self.get_conn().get_toy_color(...)
        return color
    

@dataclass
class Child:
    first_name: str
    last_name: str
    ...

    def list_all_toys(self) -> List[Toy]:
        all_toys = self.get_conn().fetch_all_toys(...)
        return [Toy(name=x.toy_name, type=x.toy_type) for x in all_toys]

    def get_favorite_toy(self) -> Optional[Toy]:
        favorite_toy = self.get_conn().fetch_favorite_toy(...)
        if not favorite_toy:
            return None
        return Toy(name=favorite_toy.toy_name, type=favorite_toy.toy_type)

(理想)用法

parent = Parent(conn_id='my-secret-connection-details')

child_1 = parent.Child(first_name='John', last_name='Doe')

for each_toy in child_1.list_all_toys():
    print(f"{child_1.first_name}'s toy {each_toy.name} is a {each_toy.get_color()} {each_toy.type}.")
    # John's toy Teddy is a white stuffed bear.

重要笔记

我考虑过使用@classmethod返回经过身份验证的实例的子类来解决这个问题。似乎很有希望,直到我意识到数据类不允许您修改它们的__init__方法。例如:

from typing import Callable, Optional
from pydantic.dataclasses import dataclass

@dataclass
class Toy:
    ...
    @classmethod
    def generate_with_connection(cls, connection: Callable, *args, **kwargs):
        return cls(*args, **kwargs, connection=connection) # Requires logic in __init__ to handle `connection`.

@dataclass
class Child:
    ...
    def get_favorite_toy(self) -> Optional[Toy]:
        favorite_toy = self.get_conn().fetch_favorite_toy(...)
        if not favorite_toy:
            return None
        return Toy.generate_with_connection(
            connection=self.get_conn,
            name=favorite_toy.toy_name,
            type=favorite_toy.toy_type
        )

问题

  1. 如何链接父类和多个子类,保证每个子类都可以访问get_conn()父类的同一个方法?我的第一个猜测是继承,但我认为它不能解决下一个问题。还有其他使用检查/追溯模块的方法吗?
  2. 我们如何确保每个子类的方法可以返回其他子类的实例,这些子类也可以访问get_conn()父类的相同方法?例如:Child.get_favorite_toy()应该返回一个可以使用相同方法Toy成功运行的实例。Toy.get_color()get_conn()

标签: pythonpython-moduletracebackinspectpython-dataclasses

解决方案


推荐阅读