繁体   English   中英

在python的主类中使用subclass属性

[英]using subclass attribute in the main class in python

我正在尝试将凭证类下的self.role设置为使用AXL类下的self.role。 想法是根据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

我需要看到r而不是rx

这是沙盒的链接

@chepner的回答绝对是正确的解决方案。 我将其保留在这里,是为了过分复杂的简单问题。

您可以在Credential上将username_file@property ,以便在访问@property不是在实例创建时对其进行评估。

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',如果为Credential实例,则为'rx'。

如果要简化,还可以缓存第一个属性访问的结果:

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

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)

好的,这里的问题基本上是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())

编辑:

只是一个简短的解释,您几乎可以将任何变量都转换为属性,选择角色的原因是资源管理。 从本质上讲,每次角色更改(程序中一次)时,在setter中更新username_file所需的资源少于每次调用getter时添加字符串(慢操作)所需的资源。 当然,考虑程序资源管理的规模不应该成为交易的障碍,而应提及解释答案的逻辑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM