链接类方法构造函数

问题描述 投票:0回答:1

Python中有一个习惯用法,即使用类方法来提供构造对象的附加方法,其中转换/转换逻辑保留在类方法中,而

__init__()
仅用于初始化字段。例如:

class Foo:
  field1: bytes

  def __init__(self, field1: bytes):
    self.field1 = field1

  @classmethod
  def from_hex(cls, hex: str) -> Foo:
    '''
    construct a Foo from a hex string like "12:34:56:78"
    '''
    return cls(field1=bytes.fromhex(hex.replace(':', ' ')))

现在,假设我定义了一个从 Foo 派生的类:

class Bar(Foo):
  field2: str

  def __init__(self, field1: bytes, field2: str):
    Foo.__init__(self, field1)
    self.field2 = field2

考虑到这个层次结构,我想定义一个构造函数

Bar.from_hex_with_tag()
,它将作为
Foo.from_hex()
的扩展:

class Bar(Foo):
  <...>

  @classmethod
  def from_hex_with_tag(cls, hex: str, tag: str) -> Bar:
    return cls(
      field1=bytes.fromhex(hex.replace(':', ' ')),  # duplicated code with Foo.from_hex()
      field2=tag
    )

如何在

Foo.from_hex()
中重复使用
Bar.from_hex_with_tag()

python python-3.x oop class-method
1个回答
0
投票
像这样

重用

classmethod
依赖于一切遵守里氏替换原则。您的子类不遵守它(它的初始化程序需要额外的参数),因此您能做的最好的事情就是提取父类中的类型转换代码(可能作为下划线前缀的
@staticmethod
实用程序),以便父类孩子也可以使用。

例如,您可能会这样做:

class Foo:
  field1: bytes

  def __init__(self, field1: bytes):
    self.field1 = field1

  @staticmethod
  def _field_from_hex(hex: str) -> bytes:
      return bytes.fromhex(hex.replace(':', ' '))

  @classmethod
  def from_hex(cls, hex: str) -> Foo:
    '''
    construct a Foo from a hex string like "12:34:56:78"
    '''
    return cls(field1=self._field_from_hex(hex))

所以

Bar
可以是:

class Bar(Foo):
  <...>

  @classmethod
  def from_hex_with_tag(cls, hex: str, tag: str) -> Bar:
    return cls(
      field1=self._field_from_hex(hex),
      field2=tag
    )
© www.soinside.com 2019 - 2024. All rights reserved.