読者です 読者をやめる 読者になる 読者になる

Pythonでインターフェース

良い方法なのかは疑問ですが、__metaclass__を使って、メソッドの定義を強制することができます。

#!/usr/bin/env python2.6
import unittest
import itertools
import sys
class EntryType(type):
  def __new__(cls, name, bases, d):
    interface = ('get_size',)
    for method in interface:
      if not d.get(method, False):
        raise Exception, 'method %s should be defined' % method
    return type.__new__(cls, name, bases, d)
class Entry(object):
  __metaclass__ = EntryType
  def __init__(self, *fields):
    assert(len(fields) == len(self.fields))
    for field, value in itertools.izip(self.fields, fields):
      setattr(self, field, value)  
  def get_size(self):
    pass
class File(Entry):
  fields = ('name', 'size')
  def get_size(self):
    return self.size
  def get_name(self):
    return self.name
class Directory(Entry):
  fields = ('name', 'entries')
  def get_size(self):
    size = 0
    for entry in self.entries:
      size += entry.get_size()
    return size
  def add(self, entry):
    self.entries.append(entry) 
class DirectTests(unittest.TestCase):
  def test_constructor(self):
    f = File('index.html', 5)
    self.assertEqual('index.html', f.name)
    d = Directory('/', [f])
    self.assertEqual('/', d.name)
    self.assertEqual([f], d.entries)
  def test_interface(self):
    try:
      class NoEntry(Entry):
        pass
    except Exception:
      self.assertEqual('method get_size should be defined',
      str(sys.exc_info()[1]))
      return
    self.fail()