ホーム > Uncategorized > 辞書でOOP

辞書でOOP

2009 年 7 月 27 日 コメントをどうぞ コメント

 西尾さんのJythonプログラミング,第5章より.
読んでいてもいまいちピンとこなかったので,写経してみた.

# -*- coding:utf-8 -*-
#!/usr/bin/env python

#from __future__ import nested_scopes

# 初期化
def __init__(self, cartype):
    self["count"] = 0
    self["cartype"] = cartype

# EntryPoint(実質のテストメソッド)
def main():
    Counter = {"__init__": __init__, "push": push}
    counter = instanciate(Counter, "Ferrari")
    for i in range(10):
        get_attr(counter, "push")()

    RedCounter = extend([Counter], {"push": red_push})
    counter = instanciate(RedCounter, "Ferrari")
    for i in range(10):
        get_attr(counter, "push")()

# 実体化
def instanciate(class_, *args):
    ins = {}
    ins["__class__"] = class_
    #get_attr(ins, "__init__")(ins, *args)
    get_attr(ins, "__init__")(*args)
    return ins

# 継承
def extend(base_classes, new_attrs):
    new_class = {"__bases__": base_classes}
    new_class.update(new_attrs)
    return new_class

# クラス属性の検索
def get_attr_from_class(class_, name):
    if class_.has_key(name):
        return class_[name]
    elif class_.has_key("__bases__"):
        for base_class in class_["__bases__"]:
            try:
                value = get_attr_from_class(base_class, name)
                return value
            except:
                pass
    raise AttributeError("no attribute '%s'" % name)

# インスタンス属性の検索
def get_attr(ins, name):
    if ins.has_key(name):
        result = ins[name]
    else:
        #result = ins["__class__"][name]
        result = get_attr_from_class(ins["__class__"], name)

    if callable(result):
        def wrapped_method(*args):
            return result(ins, *args)
        return wrapped_method
    else:
        return result

# 適当なメソッド其の壱(ex. 計数機)
def push(self):
    self["count"] += 1
    print self["count"], self["cartype"]

# 適当なメソッド其の弐(ex. 3倍早い計数機)
def red_push(self):
    self["count"] += 3
    print "red", self["count"], self["cartype"]

if __name__ == '__main__':
    main()

ふむふむ.
複数の属性をまとめ上げることがオブジェクト指向の目的なのだとすれば,確かにClassは要らない.
今までJavascriptなどのプロトタイプ的継承が「気持ち悪いなぁ」と思っていたんだけど,
上記を写経してみて,腑に落ちた.
PythonやってるとPythonそのものより多言語の理解が進むことが多い.

下記も参考になった.

Python で自前の class を作るとき、メソッドの第一引数がそのクラスのインスタンスそれ自身 (一般に self と書かれる) であることの理由を説明することです。

他の言語ではメソッドを定義するときに第一引数をインスタンスにするという方法は取り入れておらず、 this などの予約語を使ってインスタンスを表すのが一般的です。 Python だけが、独自の流儀をとっています。 しかし、このことを説明したサイトは見当たりませんでした。 どのサイトもそれは決まりごとだで済ませてしまっています。 しかし、それではどうも Python のクラスシステムを理解した気になれないので、Python でクラスシステムが どのように実装しているか推測しながら、例の self について説明したいと思います。

via: Python のクラスシステム

カテゴリー: Uncategorized タグ: , ,
  1. コメントはまだありません。
  1. トラックバックはまだありません。