web-dev-qa-db-ja.com

Python拡張メソッド

OK、C#では次のようなものがあります:

public static string Destroy(this string s) { 
    return "";
}

したがって、基本的に、文字列がある場合は次のことができます。

str = "This is my string to be destroyed";
newstr = str.Destroy()
# instead of 
newstr = Destroy(str)

私の意見ではもっと読みやすいので、これはクールです。 Pythonは似たようなものがありますか?つまり、次のように書く代わりに:

x = SomeClass()
div = x.getMyDiv()
span = x.FirstChild(x.FirstChild(div)) # so instead of this

私は書きたいです:

span = div.FirstChild().FirstChild() # which is more readable to me

なにか提案を?

28
Shaokan

クラスを直接変更することができます。これは、モンキーパッチとも呼ばれます。

def MyMethod(self):
      return self + self

MyClass.MyMethod = MyMethod
del(MyMethod)#clean up namespace

Strのような特別なクラスでこれを実行できるかどうかは100%わかりませんが、ユーザー定義クラスには問題ありません。

更新

あなたはコメントでこれがstrのようなビルトインでは不可能であるという私の疑いを確認します。その場合、そのようなクラスのC#拡張メソッドに類似したものはないと思います。

最後に、C#とPythonの両方でのこれらのメソッドの利便性には、関連するリスクが伴います。これらの手法を使用すると、コードの理解と保守がより複雑になる可能性があります。

18
David Heffernan

禁断の果実 の助けを借りてモンキーパッチを適用することにより、組み込みクラスを変更できます。

しかし、禁止されているフルーツをインストールするには、Cコンパイラ無制限の環境が必要なので、おそらくGoogle App Engine、Herokuなどで実行するには、機能しないか、ハードな努力が必要です。

このライブラリによって、トルコ語のi,I大文字/小文字の問題に対するPython 2.7のunicodeクラスの動作を変更しました。

# -*- coding: utf8 -*-
# Redesigned by @guneysus

import __builtin__
from forbiddenfruit import curse

lcase_table = Tuple(u'abcçdefgğhıijklmnoöprsştuüvyz')
ucase_table = Tuple(u'ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ')


def upper(data):
    data = data.replace('i',u'İ')
    data = data.replace(u'ı',u'I')
    result = ''
    for char in data:
        try:
            char_index = lcase_table.index(char)
            ucase_char = ucase_table[char_index]
        except:
            ucase_char = char
        result += ucase_char
    return result

curse(__builtin__.unicode, 'upper', upper)
class unicode_tr(unicode):
    """For Backward compatibility"""
    def __init__(self, arg):
        super(unicode_tr, self).__init__(*args, **kwargs)

if __name__ == '__main__':
    print u'istanbul'.upper()
3
guneysus

あなたは次のようにあなたが尋ねたことをすることができます:

def extension_method(self):
    #do stuff
class.extension_method = extension_method
0
murgatroid99