LoginSignup
9
6

More than 5 years have passed since last update.

【Python】SwiftのextensionみたいなことがPythonでやりたい

Last updated at Posted at 2019-04-24

はじめに

この記事は主に Python3 について取り扱っています.Python2 ではお話が変わってくるかもしれません

みなさんSwiftのextension(拡張メソッド,プロパティなど)ってご存知でしょうか?

まずは以下をご覧ください.

class Person {
    var name = ""

    init(name: String) {
        self.name = name
    }
}

extension Person {
    func say_hello() {
        print("Hello, my name is " + self.name)
    }
}

var p = Person(name: "Tom")
p.say_hello()

出力

Hello, my name is Tom

このように既存のクラスに対してメソッドとかを直接拡張することができます.
まあこの程度なら最初からPersonにsay_hello()実装すればよくね?って思うわけです.

ところがこんなこともできます.

import Foundation

extension String {
    func remove_spaces() -> String {
        return self.replacingOccurrences(of: " ", with: "")
    }
}


print("hello world !".remove_spaces())

出力

helloworld!

そうです,既存のクラスでもextensionすることができます.

Python でもやりたい!

以下のようにしてそれっぽく出来ます.

class Person():
    def __init__(self, name):
        self.name = name


def ex_func(self):
    print("Hello, my name is", self.name)


Person.say_hello = ex_func

p = Person("Tom")

p.say_hello()

出力

Hello, my name is Tom

やったぜ。

じゃあこれもきっと......

def ex_func(self):
    return self.replace(" ", "")

str.remove_spaces = ex_func

print("hello world !")

あるぇ??

TypeError: can't set attributes of built-in/extension type 'str'

built-inクラスは拡張できないようです.

禁断の果実

まずはやってみよう

forbiddenfruitというライブラリをインストールしましょう.

pip install forbiddenfruit
from forbiddenfruit import curse
def remove_spaces(self):
    return self.replace(" ", "")

curse(str, "remove_spaces", remove_spaces)
print("hello world !".remove_spaces())

やったぜ。

helloworld!

使い方

登録

curse([built-inクラス], [登録名], [メソッドとか])

禁断の果実とか呪うとかなんだか恐ろしいライブラリですね.

解除

from forbiddenfruit import reverse

reverse([built-inクラス], [登録名])

どういう仕組みなんだこれ......

extension の難点

こうして見るとなかなかに便利で可読性が上がりそうな extension ですが,多用するのはあまり良くないと思います.
とりわけPythonは任意のタイミングで付与することができ,さらに既にインスタンスを生成済みのオブジェクトにまで影響を及ぼすためです.

また以下のような難点も有ります.
extension はある意味クラスを継承せずとも,新たなメソッドやプロパティなどを追加できます.
しかし,他人からしたら知らないメソッドなどをいつでも追加できてしまう というのは可読性を下げうる欠点となりえます.

ある人にとっての remove_spaces半角スペースを削除するメソッドであっても,ある人にとっては全角スペースを削除するメソッドとして想定しているかもしれません.
同じ str,同じ意味の名前のメソッドで挙動が異なると多くの人は混乱するでしょう.

このような混乱を避けるためにbuilt-inクラスに関しては拡張できないように制限されているのかもしれませんね.

参考

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6