Zusammenfassung der Klassenverwendung in Python

Ein interner Aufruf und __call__()

Detaillierte Referenz: https://blog.csdn.net/weixin_43593330/article/details/108174666
Beachten: Doppelt führende und doppelt endende Unterstriche __var__ werden für spezielle Zwecke in Python verwendet. Weitere Informationen finden Sie unter: https://www.runoob.com/w3cnote/python-5-underline.html, aber nicht alle dieser Typen können verwendet werden Ein Objekt kann aufgerufen werden, __call__ ist standardmäßig in Python implementiert, __getitem__ ist in Torch.utils.data.Dataset von Pytorch implementiert und __getitem__ ist in keras.utils.Sequence von Keras implementiert.

Fünf Bedeutungen von Unterstrichen in Python: einzelner führender Unterstrich _var, einzelner nachfolgender Unterstrich var_, doppelter führender Unterstrich __var, doppelter führender und abschließender Unterstrich __var__, einfacher Unterstrich_Referenz: https://www.runoob.com/w3cnote/python-5-underline . html.

Doppelter Unterstrich __xxx__ (magische Methode) Referenz in Python: https://www.cnblogs.com/bigtreei/p/7930511.html

call () ist eine magische Methode. Durch die Implementierung dieser Methode in einer Klasse kann die Instanz (das Objekt) der Klasse wie eine Funktion aufgerufen werden. Standardmäßig ist diese Methode nicht in der Klasse implementiert.

Die Funktion der Methode call () besteht eigentlich darin, ein instanziiertes Objekt einer Klasse in ein aufrufbares Objekt umzuwandeln, sofern die Methode __call__() in der Klasse implementiert ist. Wenn beispielsweise __call__() nicht in der Klasse implementiert ist, ist das Objekt p zu diesem Zeitpunkt nur eine Instanz der Klasse und kein aufrufbares Objekt. Beim Aufruf wird ein Fehler gemeldet: Das Objekt „Person“ ist nicht aufrufbar .

class People(object):
    def __init__(self, name):
        self.name = name

    def my_friend(self):
        print("hello "+self.name)

    def train(self,location):
        print("name"+location)

    def __call__(self):
        return self.my_friend()
        # return self.train(location)

    def update(self, newname):
        self.name = newname

a = People('无忌!')
a.__call__()       # 调用方法一
a()                # 调用方法二   调用就会直接激活__call__(),调用时必须加上括号

# 调用类中其他对象
a.update("赵敏")  # 更新类中变量,更新了类中的全局变量,调用时a后面不加括号
a()

Fügen Sie hier eine Bildbeschreibung ein

class People(object):
    def __init__(self, name):
        self.name = name

    def add_interest(self, interest): # 定义类中新的全局变量,也就是在类中的初始化函数中没有定义的变量。
    # 不能直接给定,必须通过这种函数方法来传入
        self.interest = interest

    def change_interest(self):  # 前面定义好新的变量后,在这里更改
        self.interest = "play guitar"

    def speak(self):  # 不需要传入参数的对象
        print("come here please")

    def train(self, location):  # 初始化时传入的参数这里不能用,需要在这个对象中传入参数,只对这个函数起作用
        print("name"+" "+location)

    def my_friend(self, location):  # 调用类中的其他对象。如果被调用函数需要参数,则传入参数
        self.change_interest()  # 不需要参数的调用
        self.speak()  # 不需要参数的调用
        self.train(location)  # 需要参数的调用
        print("hello "+" "+self.name)
        print("I like"+" "+self.interest)

    def __call__(self, location):  # __call__()方法的作用其实是把一个类的实例化对象变成了可调用对象,
    # 只要类里实现了__call__()方法就行,即实例化类后,直接调用类就会调用__call__
        return self.my_friend(location)
        # return self.train(location)

    def update(self, newname):  # 更新类中全局变量的函数
        self.name = newname

    def play(self, ball):  # 跟类中其他对象没有关系的独立对象
        print("play"+ball)

a = People('无忌!')
a.add_interest("sing song")
a.__call__("北京")  # 调用方法一
print("---------------------")
a("北京")           # 调用方法二
print("---------------------")
# 调用类中其他对象
a.update("赵敏")  # 更新类中变量
a("北京")
print("---------------------")
# 调用类中独立对象
a.play("football")
print("---------------------")
# 打印类中的全局变量
print(a.name)
print(a.interest)

Fügen Sie hier eine Bildbeschreibung ein

2. Aktualisieren Sie die globalen Variablen in der Klasse beim Schleifendurchlauf

Wenn Sie die globalen Variablen in der Klasse in der Schleife automatisch aktualisieren möchten, müssen Sie die Initialisierung der Klasse außerhalb der Schleife schreiben.

# 定义一个类
class step_batch():
    def __init__(self, lr=10):
        self.lr = lr

    def run(self):
        print(self.lr)

    def update(self):
        self.lr = self.lr / 2

# 类的初始化在循环里面,意味着每次循环都需要重新初始化,那么循环中的更新变量的操作就会被类的重新初始化给更改掉
def train_model(init_lr=10):
    for i in tqdm(range(10)):
        a = step_batch(lr=init_lr)  # 类的初始化
        a.run()
        if i % 2 == 0:
            a.update()

# 类的初始化在循环外面,意味着在进入循环之前只进行了一次初始化;在循环体内部,更新变量的操作就会将更新后的变量保存下来
def test_model(init_lr=10):
    a = step_batch(lr=init_lr)  # 类的初始化
    for i in tqdm(range(10)):
        a.run()
        if i % 2 == 0:
            a.update()

# 结果如下
类的初始化在循环中
10
10
10
10
10
10
10
10
10
10
---------------------
类的初始化在循环外面
10
5.0
5.0
2.5
2.5
1.25
1.25
0.625
0.625
0.3125
100%|██████████| 10/10 [00:00<?, ?it/s]
100%|██████████| 10/10 [00:00<?, ?it/s]

Fügen Sie hier eine Bildbeschreibung ein
Zusammenfassung:
Beim Instanziieren der StepRunner()-Klasse wird init () automatisch ausgeführt, um zu initialisieren, Parameter an die in __init__() definierten Variablen und Funktionen zu übergeben und Werte zuzuweisen.

Hinweis: Nach der Instanziierung der Klasse können Sie später die Objekte in der Klasse aufrufen und die Objekte in der Klasse ändern. Welches Objekt (Funktion) in der Klasse aufgerufen wird, das Objekt (Funktion) wird beeinflusst, und es wird nicht beeinflusst, wenn es nicht aufgerufen wird, das heißt, wenn das aufgerufene Objekt (Funktion) keine Auswirkungen auf die Variablen und Funktionen in hat init( ) Dann Wenn das aufgerufene Objekt (Funktion) eine Beziehung zum Inhalt in __init__() hat, ändern sich die Variablen und Funktionen in __init__().

Variablen in den Klassen, die zum Zeitpunkt der Initialisierung definiert werden, können auch so geändert werden, dass sie dauerhaft geändert werden. Welches wird geändert, welches ist betroffen und welches ist nicht betroffen.

Das Verwirrendste hier ist __call__() in der Klasse. Die Funktion von call() besteht darin, den in __call__() definierten Inhalt durch direkten Aufruf des Klassennamens nach der Instanziierung aufzurufen, ohne dass class( ) Achten Sie einfach darauf, was in __call__() definiert ist.

Ich denke du magst

Origin blog.csdn.net/LIWEI940638093/article/details/126691442
Empfohlen
Rangfolge