используя атрибут подкласса в основном классе в Python - PullRequest
0 голосов
/ 22 марта 2019

Я пытаюсь установить self.role под классом учетных данных, чтобы использовать self.role под классом AXL.идея состоит в том, чтобы иметь разные классы в зависимости от роли API.если класс axl только читает данные, то роль будет иметь вид r.

PATH = 'home_drive_'
PLATFORM = 'Linux_'
ITEM = '_PC'

class Credential:

    def __init__(self, path, platform):
        self.role = 'rx'
        self.username_file = path + platform + ('The role should be the same as AXL role: ' + self.role)

class AXL(Credential):

    def __init__(self, path, platform, item):
        super().__init__(path, platform)
        self.role = 'r'
        self.item = item

    def final(self):
        return self.username_file + self.item

reg1 = AXL(PATH, PLATFORM, ITEM)

print('AXL role:', reg1.role)
print(reg1.username_file)
print(reg1.final())

результат будет

AXL role: r 
home_drive_Linux_The role should be the same as AXL role: rx 
home_drive_Linux_The role should be the same as AXL role: rx_PC

Вместо rx мне нужно увидеть r

Вот ссылка на песочницу

Ответы [ 3 ]

2 голосов
/ 22 марта 2019

role должен быть параметром Credential.__init__, не жестко закодированным, хотя он может иметь значение по умолчанию для базового класса.Подклассы передают требуемую роль непосредственно super().__init__.(Если есть что-то, что должно иметь роль 'rx', это также должен быть подкласс Credential, а не Credential.)

class Credential:

    def __init__(self, path, platform, role='rx'):
        self.role = role
        self.username_file = path + platform + ('The role should be the same as AXL role: ' + role)


# class SomethingNeedingRoleRX(Credential):
#      def __init__(self, path, platform):
#          super().__init__(path, platform, 'rx')


class AXL(Credential):

    def __init__(self, path, platform, item):
        super().__init__(path, platform, 'r')
        self.item = item

    def final(self):
        return self.username_file + self.item

КомуИграйте лучше с super, вы можете использовать аргументы только для ключевых слов для __init__:

class Credential:
    def __init__(self, *, path, platform, role='rx', **kwargs):
        super().__init__(**kwargs)
        self.role = role
        self.username_file = path + platform + role


class AXL(Credential):
    def __init__(self, *, item, **kwargs):
        super().__init__(role='r', **kwargs)
        self.item = item

    def final(self):
        return self.username_file + self.item


reg1 = AXL(path=PATH, platform=PLATFORM, item=ITEM)
2 голосов
/ 22 марта 2019

Answer by @ chepner - определенно правильное решение.Я оставлю это здесь как дань уважения чрезмерной усложнению простой проблемы.

Вы можете сделать username_file a @property на Credential, чтобы оно оценивалось при доступе, а не в экземпляресоздание.

class Credential:
    def __init__(self, path, platform):
        self.role = 'rx'
        self.path = path
        self.platform = platform

    @property
    def username_file(self):
        return self.path + self.platform + self.role

Если это экземпляр AXL, то roll будет 'r' и 'rx', если экземпляр Credential.

Вы также можете кэшировать результатдоступ к первому свойству, если вы хотите оптимизировать:

class Credential:
    def __init__(self, path, platform):
        self.role = 'rx'
        self.path = path
        self.platform = platform
        self._username_file = None

    @property
    def username_file(self):
        if not self._usernme_file:
            self._username_file = self.path + self.platform + self.role
        return self._username_file
1 голос
/ 22 марта 2019

Хорошо, проблема здесь в основном в типе данных username_file;это строка, созданная в конструкторе и не обновляющаяся, когда это делают компоненты.Есть несколько способов обойти это, использование свойств - довольно хороший и чистый способ сделать это:

PATH = 'home_drive_'
PLATFORM = 'Linux_'
ITEM = '_PC'


class Credential:
    def __init__(self, path, platform):
        self.path = path
        self.platform = platform
        self.role = 'rx'
        self.username_file = self.path + self.platform + ('The role should be the same as AXL role: ' + self.role)

    @property
    def role(self):
        return self._role

    @role.setter
    def role(self, new_role):
        self._role = new_role
        self.username_file = self.path + self.platform + ('The role should be the same as AXL role: ' + self.role)


class AXL(Credential):
    def __init__(self, path, platform, item):
        super().__init__(path, platform)
        self.role = 'r'
        self.item = item

    def final(self):
        return self.username_file + self.item


reg1 = AXL(PATH, PLATFORM, ITEM)

print('AXL role:', reg1.role)
print(reg1.username_file)
print(reg1.final())

РЕДАКТИРОВАТЬ:

Просто короткийПо объяснению, вы можете обратиться к свойству практически любой переменной, причина выбора роли - управление ресурсами.По сути, требуется меньше ресурсов для обновления username_file в установщике при каждом изменении роли (один раз в программе), чем при добавлении строк (медленная работа) при каждом вызове получателя.Разумеется, учитывая размер управления программными ресурсами, следует не нарушать договоренности, а упомянуть, чтобы объяснить логику ответа.

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