Вызов функции дочернего класса для уменьшения репликации кода - PullRequest
2 голосов
/ 18 октября 2019

Я пытаюсь уменьшить репликацию кода в моих дочерних классах, используя общий код в родительском классе, но все же необходимо выполнить некоторую специфическую обработку, которая изменяется в зависимости от дочернего класса. Я знаю, что звонить ребенку от родителей плохо. Как я могу выполнить сокращение кода? (или я должен даже пытаться?)

Это пример:

class Address:

    def __init__(self, street, city, postal_code):

        self._street = street
        self._city = city
        self._postal_code = self.valid_postal_code(postal_code)

    def valid_postal_code(self, postal_code):
        """ Returns a validated postal code """
        #
        # A big bunch of code common to all postal codes
        #

        if child == Usa:
            return Usa.valid_postal_code(postal_code)
        else:
            return Canada.valid_postal_code(postal_code)    

class Usa(Address):

    def valid_postal_code(self, postal_code):
        """ Returns a validated US zip code """
        # Must be 5 digits or 5 digits plus dash 4 digits
        if len(postal_code) != 5 and len(postal_code) != 10:
            raise Exception("Bad postal code")

        return postal_code


class Canada(Address):

    def valid_postal_code(self, postal_code):
        """ Returns a validates Canadian postal code """
        # Must be A#A #A#
        if len(postal_code) == 6:
            postal_code = postal_code[0:3] + " " + postal_code[3:3]
        if len(postal_code) != 7:
            raise Exception("Bad postal code")

        return postal_code.upper()

Ответы [ 2 ]

0 голосов
/ 18 октября 2019

Существует две возможности:

  • если родительский код содержит общие части, а дочерний элемент содержит специфику
    • родитель должен вернуть промежуточный результат

или

  • имеют два родительских метода, один из которых является заглушкой и переопределяется дочерним
    • родительский элемент передает промежуточный результат в заглушку

Второй метод выглядит примерно так:

class Address:

    def __init__(...):

    def valid_postal_code(self, postal_code):
        """ Returns a validated postal code """
        #
        # A big bunch of code common to all postal codes
        #
        return self._validate_postal_code(postal_code)

    def _validate_postal_code(self, postal_code):
        raise NotImplementedError


class Usa(Address):

    def _validate_postal_code(self, postal_code):
        """ Returns a validated US zip code """
        # Must be 5 digits or 5 digits plus dash 4 digits
        if len(postal_code) != 5 and len(postal_code) != 10:
            raise Exception("Bad postal code")
        return postal_code


class Canada(Address):

    def _validate_postal_code(self, postal_code):
        """ Returns a validates Canadian postal code """
        # Must be A#A #A#
        if len(postal_code) == 6:
            postal_code = postal_code[0:3] + " " + postal_code[3:3]
        if len(postal_code) != 7:
            raise Exception("Bad postal code")
        return postal_code.upper()
0 голосов
/ 18 октября 2019

Каждый метод переопределения должен вызывать родительский метод.

class Address:

    def __init__(self, street, city, postal_code):

        self._street = street
        self._city = city
        self._postal_code = self.valid_postal_code(postal_code)

    def valid_postal_code(self, postal_code):
        """ Returns a validated postal code """
        #
        # A big bunch of code common to all postal codes
        #
        ...


class Usa(Address):

    def valid_postal_code(self, postal_code):
        """ Returns a validated US zip code """

        # Must be 5 digits or 5 digits plus dash 4 digits
        if not super().valid_postal_code(postal_code) or len(postal_code) != 5 and len(postal_code) != 10:
            raise Exception("Bad postal code")

        return postal_code


class Canada(Address):

    def valid_postal_code(self, postal_code):
        """ Returns a validates Canadian postal code """
        # Must be A#A #A#
        if len(postal_code) == 6:
            postal_code = postal_code[0:3] + " " + postal_code[3:3]
        if not super().valid_postal_code() or len(postal_code) != 7:
            raise Exception("Bad postal code")

        return postal_code.upper()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...