91

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

JavaScript には、このように動作するプロトタイプ オブジェクトがあります。多分それは悪い設計であり、dict オブジェクトをサブクラス化する必要がありますが、それはサブクラスでのみ機能し、将来のすべての辞書で機能するようにしたいと考えています。

JavaScript では次のようになります。

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

これは、より多くの例を含む便利なリンクです— http://www.javascriptkit.com/javatutors/proto3.shtml

4

8 に答える 8

93

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

これがどのように見えるかです

# 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'
"""
于 2011-01-15T07:47:38.927 に答える
1

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

いいえ、これは混乱を招くため、実際の辞書がこのタイプを持つことを意味するものではありません。組み込み型のサブクラス化は、機能を追加するための推奨される方法です。

于 2011-01-15T07:30:31.183 に答える
0

はい、組み込みの Python 型にカスタム メソッドと属性を追加できます。たとえば、リスト クラス内に新しいメソッドを定義するとします。

「リスト」クラスを定義し、次のように独自の関数を作成することを考えてみましょう:

class list:
    def custom_method (self):
       return("Hey, I'm a custom method of list class")
#lets create an object here
obj = list([1,2,3])

print(obj.custom_method())
#The above runs fine, but a list has append() method also right?? let's try it

print(obj.append(1))
"""Now you will get Attribute error : list object has no attribute append()"""

クラス名として「リスト」を持つクラスを定義すると、「リスト」は組み込みクラスではなくユーザー定義クラスとして扱われるため、「組み込みリスト」クラス メソッドにアクセスできなくなるためです。

したがって、このエラーを取り除くために、「リスト」クラスのプロパティ/メンバーを継承し、独自のメソッドまたは属性を定義できます。したがって、このようにして、同じクラス名を使用して、ユーザー定義/組み込みのクラス メソッドを呼び出すことができます。

外観は次のとおりです。

#Extending in-built list class
class list(list):
     def custom_method (self):
         return("Hey, I'm a custom method of list class")
obj = list([1,2,3])
print(obj.custom_method())
obj.append(1)
print(obj)

正常に実行され、変更されたリストが [1,2,3,1] として出力されます。

注:ただし、このようにすると、長期的には名前の競合などのあいまいな問題が発生する可能性があります

たとえば、ユーザー定義クラス (ここでは「リスト」とします) の組み込み関数と同じシグネチャを持つメソッドがある場合、知らないうちに、または通知なしにオーバーライドされるため、元のメソッドを使用できない場合があります。今後の機能。上記のコードを考えると、 のようなメソッドを定義するとappend(self, value)、append() の本来の機能が失われます。

したがって、組み込みクラス名と同じ名前ではなく、クラス名に別のクラス名を使用することをお勧めします

たとえば、次のようにクラスを宣言すると、エラーが発生したり、名前の競合に直面したりすることはありません。

class custom_list(list):
     def custom_method (self):
         return("Hey, I'm a custom method of list class")
obj = custom_list([1,2,3])
print(obj.custom_method())
obj.append(1)
print(obj)
于 2021-11-26T14:51:13.427 に答える