web-dev-qa-db-ja.com

カスタムメソッド/属性を組み込みのPythonタイプに追加できますか?

たとえば、Pythonのdict型にhelloWorld()メソッドを追加するとします。これはできますか?

JavaScriptには、このように動作するプロトタイプオブジェクトがあります。おそらくデザインが悪いので、dictオブジェクトをサブクラス化する必要がありますが、サブクラスでのみ動作し、将来のすべてのディクショナリで動作するようにしたいと思います。

JavaScriptでどのようにダウンするかを以下に示します。

String.prototype.hello = function() {
    alert("Hello, " + this + "!");
}
"Jed".hello() //alerts "Hello, Jed!"

他の例との便利なリンクを次に示します。 http://www.javascriptkit.com/javatutors/proto3.shtml

59
jedmao

メソッドを元の型に直接追加することはできません。ただし、型をサブクラス化してから、ビルトイン/グローバル名前空間に置き換えることで、必要な効果のほとんどを達成できます。残念ながら、リテラル構文で作成されたオブジェクトは引き続きVanilla型であり、新しいメソッド/属性はありません。

こんな感じです

# Built-in namespace
import __builtin__

# Extended subclass
class mystr(str):
    def first_last(self):
        if self:
            return self[0] + self[-1]
        else:
            return ''

# Substitute the original str with the subclass on the built-in namespace    
__builtin__.str = mystr

print str(1234).first_last()
print str(0).first_last()
print str('').first_last()
print '0'.first_last()

output = """
14
00

Traceback (most recent call last):
  File "strp.py", line 16, in <module>
    print '0'.first_last()
AttributeError: 'str' object has no attribute 'first_last'
"""
63
TryPyPy

Forbbidenfruitを試してみてください!

ここにコードがあります、非常に簡単です!

from forbiddenfruit import curse


def list_size(self):
    return len(self)

def string_hello(self):
    print("Hello, {}".format(self))

if __== "__main__":
    curse(list, "size", list_size)
    a = [1, 2, 3]
    print(a.size())
    curse(str, "hello", string_hello)
    "Jesse".hello()
1
dameng

はい、これらの型をサブクラス化することにより。 Pythonでの型とクラスの統合 を参照してください。

いいえ、これは実際の辞書がこのタイプを持つという意味ではありません。それは混乱を招くからです。機能を追加するには、組み込み型のサブクラス化をお勧めします。

1
Rafe Kettler
class MyString:
    def __init__(self, string):
        self.string = string
    def bigger_string(self):
        print(' '.join(self.string))

mystring = MyString("this is the string")
mystring.bigger_string()

出力

t h i s   i s   t h e   s t r i n g

Python 3.7のデータクラス

from dataclasses import dataclass

@dataclass
class St:

    text : str

    def bigger(self) -> None:
        self.text = list(self.text)
        print(" ".join(self.text))

mys = St("Hello")
mys.bigger()

出力

H e l l o
0
Giovanni Python