30

このPythonドキュメントページには次 のように書かれています。

そのアイデンティティと同様に、オブジェクトのタイプも変更できません。

そして、私はこのスクリプトを試します、

#!python3  

class Foo:
  num = 1
  pass

class Bar:
  num = 2
  pass

f1,f2= Foo(), Foo()

f2.__class__ = Bar
print( type(f1), type(f2), f1.num, f2.num )

結果は次のとおりです。

<class '__main__.Foo'> <class '__main__.Bar'> 1 2

typeのを変更したと思いますf2
何が問題なのですか、何が欠けていますか?

4

4 に答える 4

20

そのページの脚注は次のとおりです。

[1]場合によっては、特定の制御された条件下で、オブジェクトのタイプを変更することが可能です。ただし、誤って処理すると非常に奇妙な動作を引き起こす可能性があるため、一般的にはお勧めできません。

__class__f2のを次のように変更しようとした場合list

f2.__class__ = list

TypeErrorが発生しました:

TypeError: __class__ assignment: only for heap types
于 2013-03-14T08:41:43.360 に答える
15

いつ、どのようにこれを行うか

タイプを変更する(「キャスト」)ことは、変更できないコードによって作成されたオブジェクトに機能を追加する場合に意味があります。

あるステートメントobj = some_call_to_a_library()がクラスのオブジェクトを与えると仮定しますA。たとえば、追加の機能を追加する必要がありますmymethod()。次に、次のようなサブクラスを導入できますMyA(Python 3スタイル)。

class MyA(A):
    @classmethod
    def cast(cls, some_a: A):
        """Cast an A into a MyA."""
        assert isinstance(some_a, A)
        some_a.__class__ = cls  # now mymethod() is available
        assert isinstance(some_a, MyA)
        return some_a

    def mymethod(self):
        ...

そして、と書きobj = MyA.cast(some_call_to_a_library())ます。追加の属性(ファクトリメソッド)MyAに依存する場合は、それらを作成する必要があります。cast

requests.Response永続化してファイルへの応答またはファイルからの応答を取得できるバージョンが必要なときに、このようなことをしました。

于 2018-04-12T11:56:12.030 に答える
3

今日、同僚からこの質問がありました。彼には、初期化時の入力に基づいて、自動的に子の1つになるように昇格させたい親クラスがありました。次のスクリプトは、概念実証として機能しました。

class ClassB(object):

    def __init__(self):
        self.__class__ = ClassA

    def blah2(self,t):
        print('I give you',t)
        return 'You are welcome'

class ClassA(ClassB):

   def blah(self, t):
       print('you gave me',t)
       return 'Thankyou'



a = ClassB()
print(type(a))
print(a.blah('sausage'))
print(a.blah2('cabbage'))

結果は次のとおりです。

<class '__main__.ClassA'>
you gave me sausage
Thankyou
I give you cabbage
You are welcome

これは、親関数と子関数の両方がで使用できるようになったことを示していますA

于 2017-12-01T17:31:13.437 に答える
3

古い質問ですが、Pythonオブジェクトのタイプを安全に拡張するためのテクニックがあります。

def extendObject(obj):
    # Our extended type is explicitly derived from our existing type.
    class Extended(obj.__class__):
        # Whatever extensions you want to make.
        def someMethod(self):
            pass
    # Change the type of the object.
    obj.__class__ = Extended
    return obj
于 2019-03-08T09:39:25.650 に答える