Binden Sie Methoden an Python-Klassen und -Instanzen

Da Python eine dynamische Sprache ist, können Sie Klassen und Instanzen zur Laufzeit dynamisch neu definieren und Methoden hinzufügen.

class User:
    pass

user1 = User()
user1.set_username('kaito')

Das Aufrufen einer undefinierten Eigenschaft oder Methode führt zu einem Fehler.


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-30-815371892d44> in <module>
      3 
      4 user1 = User()
----> 5 user1.set_username('kaito')

AttributeError: 'User' object has no attribute 'set_username'

Sie können später Methoden hinzufügen, indem Sie MethodType </ code> verwenden. Definieren Sie zunächst die Methode als Funktion (Sie müssen sich selbst als Argument wie eine Methode definieren).

def set_username(self, username):
    self.username = username

Binden Sie dann die Methode an die Instanz.

from types import MethodType
user1.set_username = MethodType(set_username, user1)
user1.set_username('kaito')
user1.set_username

Sie können sehen, dass es als Methode gebunden ist.

<bound method set_username of <__main__.User object at 0x111f55438>>

Was passiert, wenn ich direkt ohne Verwendung von MethodType </ code> zuweise?

user1.set_username = set_username
user1.set_username

Es ist nur eine Referenz auf ein Funktionsobjekt.

<function __main__.set_username(self, username)>

Versuchen Sie es auszuführen.

user1.set_username(user1, 'kaito') 

Es ist eine Funktion, keine Methode, also weist es sich nicht selbst zu.

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-42-70cc4337e082> in <module>
----> 1 user1.set_username('kaito')

TypeError: set_username() missing 1 required positional argument: 'username'

Es kann ausgeführt werden, indem man sich explizit selbst gibt.

user1.set_username(user1, 'kaito')

Was ist mit der Benutzerklasse?

User.set_username

Ich habe es nur der Instanz hinzugefügt, damit sich die Klasse nicht ändert.

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-38-40cdce039232> in <module>
----> 1 User.set_username

AttributeError: type object 'User' has no attribute 'set_username'

Wenn Sie einer Klasse eine Methode hinzufügen möchten, können Sie dies auf die gleiche Weise tun.

User.set_username = MethodType(set_username, User)
User.set_username

Die Speicheradresse wird nicht wie die Instanz angezeigt, aber ordnungsgemäß hinzugefügt.

<bound method set_username of <class '__main__.User'>>

Recommended Posts