在Python中允许子类化的不可变类型

2024-09-30 12:14:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我想要一个不可变的类型,理想情况下,可以整理自己的哈希和相等,但可以很容易地子类化。我开始使用^{}

class Command(namedtuple('Command', 'cmd_string')):

  def valid_msg(msg):
    return True

  def make_command(msg):
    if self.valid_msg(msg):
      return '%s:%s' % (self.cmd_string, msg)
    else:
      raise ValueError(INVALID_MSG)

…但这并不适合子类化。直接子类化这意味着元组的名称保持不变(用于打印。。。没什么大不了的),但更重要的是不能添加字段:

^{pr2}$

简单地创建另一个命名元组(根据文档)意味着我不继承任何方法!在

做这种事最简单最简单的方法是什么?我打算有Command的多个子类(例如十六进制文本、1-or-0等),但并不复杂。善用多重继承不是必要的。在


Tags: 方法selfcmd类型stringreturndef情况
1条回答
网友
1楼 · 发布于 2024-09-30 12:14:33

这里有一个元类来做你想做的(我想)。它的工作原理是将要继承的方法存储在字典中,然后手动将它们插入到新类字典中。它还存储传递给namedtuple构造函数的属性字符串,并将其与子类中的属性字符串合并。然后它将其传递给namedtuple,并返回一个从结果namedtuple继承的类及其字典中所有适当的方法。因为元类是从abc.ABCMeta派生的,所以可以免费进行工作类型检查。以下是构造几个类的外观:

class Foo(object):
    __metaclass__ = ImmutableMeta
    _attributes_ = 'a b'

    def sayhi(self):
        print "Hello from {0}".format(type(self).__name__)

class Bar(Foo):
    _attributes_ = 'c'

    def saybye(self):
        print "Goodbye from {0}".format(type(self).__name__)

这是元类:

^{pr2}$

这里有一些微不足道的测试代码。在

a = Foo(1, 2)
a.sayhi()

b = Bar(1, 2, 3)
b.sayhi()  # 'inherited' from class Foo
b.saybye()

try:
    b.c = 1         # will raise an AttributeError
except AttributeError:
    print "Immutable"

print "issubclass(Bar, Foo): {0}".format(issubclass(Bar, Foo))

try:
   d =  {b: 1}        # No problems
except TypeError:
    print "Cant put it in a dict"
else:
    print "Can put it in a dict"

希望有帮助。如果您不希望将每个方法附加到每个应该继承它的类上,那么您还可以提供一个默认的__getattr__,它可以查看元类字典并从中找到合适的方法。这需要某种方式将基类硬编码到方法中,可能使用闭包。在

相关问题 更多 >

    热门问题