Detaillierte Einführung in Python-Dekoratoren
Der Dekorator selbst ist eine Python-Funktion, die es anderen Funktionen ermöglicht, zusätzliche Funktionen hinzuzufügen, ohne Codeänderungen vorzunehmen. Der Rückgabewert des Dekorators ist ebenfalls ein zusätzliches Objekt .
Lassen Sie uns zunächst einige Definitionen verstehen:
1, Funktion
In Python werden Funktionen über das Schlüsselwort def, den Funktionsnamen und die optionale Parameterliste definiert. Geben Sie einen Wert über das Schlüsselwort return zurück. Nehmen wir ein Beispiel, um zu veranschaulichen, wie eine einfache Funktion definiert und aufgerufen wird:
#coding:UTF8 def foo(): return 1 print foo() 1
Methodenkörper (dasselbe gilt natürlich auch auf mehrere Zeilen) Es ist notwendig, durch Einrückung ausgedrückt, und die Funktion kann durch Hinzufügen doppelter Klammern () nach dem Methodennamen
2, Umfang
< aufgerufen werden 🎜>In Python erstellt eine Funktion einen neuen Bereich. Python-Entwickler sagen möglicherweise, dass Funktionen ihren eigenen Namensraum haben. Das bedeutet, dass sich die Funktion zunächst in ihrem eigenen Namensraum befindet. Um ein einfaches Beispiel für den lokalen und globalen Bereich zu geben
#coding:UTF8 a_string = "This is a global variable" def foo(): print locals() print globals() # doctest: +ELLIPSIS foo() #2 {'foo': <function foo at 0x00000000026ECF98>, ...., 'a_string': 'This is a global variable',...} {}
Eingebaute Funktion globals Gibt zurück Ein Feld, das alle dem Python-Interpreter bekannten Variablennamen enthält (wobei ein Teil davon weggelassen wird). In #2 wird die Funktion foo aufgerufen, um den Inhalt des lokalen Bereichs am Ende der Funktion auszugeben foo verfügt über einen eigenen unabhängigen Namespace. Auch wenn sich im temporären Namespace nichts befindet.
3, Regeln für die Variablenauflösung
Natürlich das bedeutet nicht, dass Sie in einer Funktion nicht auf die Außenwelt zugreifen können. In den Bereichsregeln von Python wird beim Erstellen einer Variablen definitiv eine Variable im aktuellen Bereich erstellt, beim Zugriff oder Ändern einer Variablen wird jedoch nach der Variablen im aktuellen Bereich gesucht. Wenn keine passende Variable gefunden wird, wird sie im geschlossenen Bereich Search.so nach oben verschoben. Wenn Sie die Funktion foo so ändern, dass sie globale Bereichsvariablen ausgibt, ist dies auch möglich
#coding:UTF8 a_string = "This is a global variable" def foo(): print a_string #1 foo() This is a global variable
bei #1 versucht der Python-Interpreter, die Variable a_string zu finden. Natürlich kann sie nicht im lokalen Bereich der Funktion gefunden werden, daher wird nach
in gesucht Wenn der globale Gültigkeitsbereich jedoch innerhalb der Funktionsvariablenzuweisung angegeben wird, sind die Ergebnisse unterschiedlich
#coding:UTF8 a_string = "This is a global variable" def foo(): a_string='Test' #1 print locals() foo() {'a_string': 'Test'} print a_string #2 This is a global variable
Auf globale Variablen kann zugegriffen werden (sofern auf sie zugegriffen werden kann). Der Datentyp (wie Liste, Diktat usw.) kann sogar geändert werden, aber die Zuweisung Nr. 1 innerhalb der Funktion funktioniert nicht Erstellt tatsächlich eine neue lokale Variable und versteckt die Variable mit demselben Namen im globalen Bereich. Sie können den Inhalt des globalen Namespace ausdrucken, um diese Schlussfolgerung zu ziehen. Sie können auch sehen, dass sich der bei #2 gedruckte a_string nicht geändert hat 🎜>
4, VariablenlebensdauerEs ist erwähnenswert, dass Variablen nicht nur in Namespaces leben, sondern auch ihre eigenen Lebenszyklen haben, wie folgt:
#coding:UTF8 def foo(): x = 1 foo() print x # 1 NameError: name 'x' is not defined
Der Fehler, der bei #1 auftritt, wird nicht nur durch Bereichsregeln verursacht, sondern auch Bezieht sich auf den Mechanismus der Funktionsaufrufimplementierung in Python und vielen anderen Programmiersprachen. Der Ausführungszeitpunkt hier ist keine gültige Syntax, um den Wert der Variablen x zu erhalten, da er überhaupt nicht existiert. Der Namespace der Funktion foo beginnt mit Aufruf der Funktion und wird zerstört, wenn er beendet wird
5, Funktionsparameter
Python ermöglicht die Übergabe von Parametern an Funktionen, und die Parameter werden lokale Variablen und existieren innerhalb der Funktion
#coding:UTF8 def foo(x): print locals() foo(1) {'x': 1}
在#1处定义了函数foo,有一个位置参数x和一个命名参数y 在#2通过常规的方式来调用函数,即使只有一个命名参数,但参数依然可以通过位置参数传递给函数.在调用函数的时候,对于命名参数y也可以完全不管就想#3所示一样.如命名参数没有接收到任何值的话,Python会自动使用声明的默认值.但不能省略第一个位置参数x,否则会像#4发生错误
python支持函数调用时的命名参数。看看#5处的函数调用,传递的是两个命名实参,这个时候因为有名称标识,参数传递的顺序也就不用在意了。
当然相反的情况也是正确的:函数的第二个形参是y,但通过位置的方式传递值给它。在#2处的函数调用foo(3,1),我们把3传递给了第一个参数,把1传递给了第二个参数,尽管第二个参数是一个命名参数。
6,嵌套函数
Python允许创建嵌套函数,就意味着可以在函数里定义函数而且现有的作用域和变量生存周期依旧适用
#coding:UTF8 def outer(): x = 1 def inner(): print x # 1 inner() # 2 outer() 1
Python解释器需找一个叫x的本地变量,查找失败之后会继续向上层的作用域里查,这个上层的作用域定义在另外一个函数里,对于函数outer来说,变量x是一个本地变量
函数inner可以访问封闭的作用域.在#2处,可以调用函数inner,inner也仅仅是一个遵循Python变量解析规则的变量名,Python解释器会优先在outer的作用域里面对变量名inner查找匹配的变量
7,函数是Python世界中的一级类对象
在Python里函数和其他东西一样都是对象
#coding:UTF8 print issubclass(int, object) # all objects in Python inherit from a common baseclass True def foo(): pass print foo.__class__ # 1 <type 'function'> print issubclass(foo.__class__, object) True
函数在Python里就是对象,和其他一样,在Python里,函数只是一些普通的值而已,也就是说把函数像参数一样传递给其他的函数或者从函数里返回函数,如:
#coding:UTF8 def add(x, y): return x + y def sub(x, y): return x - y def apply(func, x, y): # 1 return func(x, y) # 2 print apply(add, 2, 1) # 3 3 print apply(sub, 2, 1) 1
在#1处看到函数准备接收一个函数的变量,只是一个普通的变量而已,和其他变量一样,在#2处调用传进来的函数:"()代表这调用函数的操作并且调用变量包含额值.在#3处,能看到传递函数并没有特殊的用法".函数的名称只是跟其他变量一样的标识符而已
Python把频繁要用的操作变成函数作为参数进行使用,向通过传递一个函数给内置排序函数的key参数 从而 来自定义排序规则
#coding:UTF8 def outer(): def inner(): print "Inside inner" return inner # 1 foo = outer() #2 print foo <function inner at 0x000000000269C048> foo() Inside inner
在#1处恰好是函数标识符的变量inner作为返回值返回出来 "把函数inner返回出来,否则它根本不可能会被调用到" 每次函数outer呗调用,函数inner都会被重新定义,如果它不被当做变量返回额话,每次执行过后将不复存在
在#2处捕获返回值--函数inner,将它存在一个新的变量foo里.当对foo进行求值,确定包含函数inner,而且能够对它进行调用
8,闭包
#coding:UTF8 def outer(): x = 1 def inner(): print x # 1 return inner foo = outer() print foo.func_closure (<cell at 0x00000000026861F8: int object at 0x0000000001E279A8>,)
x是outer里的一个局部变量,当函数inner在#1处打印x时,Python解释器会在inner内部查找相应的变量,事实也查不到,接着会到封闭作用域里查找,并且找到匹配
从变量的生存周期来看,变量x是函数outer的一个本地变量,意味着只有当函数outer正在运行时才会存在,根据Python运行模式,无法再函数outer返回之后继续调用函数inner,在函数inner调用时,变量x早已不复存在,可能会发生一个运行时的错误
但返回的函数inner可以继续工作,Python支持一个叫做函数闭包的特性,嵌套定义在非全局作用域里的函数能够记住它在被定义的时候它所处的封闭命名空间,这能够通过查看函数的func_closure属性得出结论,这个属性里面包含封闭作用域里面的值(只会包含被捕捉到的值,比如x,如果在outer里面还定义了其他的值,封闭作用域里面是不会有的)
每次函数outer被调用的时候,函数inner都会被重新定义。现在变量x的值不会变化,所以每次返回的函数inner会是同样的逻辑
稍微改动下:
#coding:UTF8 def outer(x): def inner(): print x # 1 return inner print1 = outer(1) print2 = outer(2) print1() 1 print2() 2
从中可以看到闭包--被函数记住的封闭作用域--能够被用来创建自定义的函数,本质上是一个硬编码的参数.事实上并不是传递参数1或者2给函数inner,实际上是创建了能够打印各种数字的各种自定义版本
闭包单独拿出来就是一个非常强大的功能,在某些方面:outer像是给inner服务器的构造器,x像是一个私有变量
9,装饰器
装饰器其实就是一个闭包,把一个函数当做参数然后返回一个替代版参数
#coding:UTF8 def outer(func): def inner(): print "before func" ret = func() # 1 return ret + 1 return inner def foo(): return 1 decorated = outer(foo) # 2 print decorated() before func 2
定义了一个函数outer,只有一个func参数,在其定义了嵌套的函数inner,inner会打印一串字符串,然后调用func,在#1得到返回值,在outer每次调用时func值可能会不一样,但不管怎用,都会调用它,最后,inner返回func()+1的值,通过调用在#2处存储decorated里的函数能够看到被打印出来的字符串以及返回值2,而不是期望中调用函数foo得到的返回值1。
可以认为变量decorated是函数foo的一个装饰版本,一个加强版本。事实上如果打算写一个有用的装饰器的话,可能会想愿意用装饰版本完全取代原先的函数foo,这样总是会得到我们的”加强版“foo。想要达到这个效果,完全不需要学习新的语法,简单地赋值给变量foo就行了:
foo = outer(foo)
现在,任何怎么调用都不会牵扯到原先的函数foo,都会得到新的装饰版本的foo,现在还是来写一个有用的装饰器
#coding:UTF8 import time def bar(): time.sleep(2) print('in the bar') def test2(func): print(func) return func # print(test2(bar)) bar=test2(bar) bar() #run bar <function bar at 0x00000000026BCF98> in the bar
10. 使用 @ 标识符将装饰器应用到函数和利用*args and **kwargs
Python2.4支持使用标识符@将装饰器应用在函数上,只需要在函数的定义前加上@和装饰器的名称。在上一节的例子里我们是将原本的方法用装饰后的方法代替:
bar=test2(bar)
这种方式能够在任何时候对任意方法进行包装。但是如果自定义一个方法,可以使用@进行装饰:
1 #coding:UTF8 2 3 import time 4 5 def test2(func): 6 print(func) 7 return func 8 @test2 9 def bar():10 time.sleep(2)11 print('in the bar')12 13 bar() #run bar
1 #coding:UTF8 2 3 import time 4 def timer(func): #timer(test1) func=test1 5 def deco(*args,**kwargs): 6 start_time=time.time() 7 func(*args,**kwargs) #run test1() 8 stop_time = time.time() 9 print("the func run time is %s" %(stop_time-start_time))10 return deco11 @timer #test1=timer(test1)12 def test1():13 time.sleep(1)14 print('in the test1')15 16 @timer # test2 = timer(test2) = deco test2(name) =deco(name)17 def test2(name,age):18 print("test2:",name,age)19 20 test1()21 test2("Tom",22)22 23 24 in the test125 the func run time is 1.0520000457826 ('test2:', 'Tom', 22)27 the func run time is 0.0
下面贡献一个高级版的装饰器:
1 #coding:utf8 2 import time 3 user,passwd = 'hbert','abc' 4 def auth(auth_type): 5 print("auth func:",auth_type) 6 def outer_wrapper(func): 7 def wrapper(*args, **kwargs): 8 #print("wrapper func args:", *args, **kwargs) 9 if auth_type == "local":10 username = raw_input("Username:").strip()11 password = raw_input("Password:").strip()12 if user == username and passwd == password:13 print("\033[32;1mUser has passed authentication\033[0m")14 res = func(*args, **kwargs) # from home15 print("---after authenticaion ")16 return res17 else:18 exit("\033[31;1mInvalid username or password\033[0m")19 elif auth_type == "ldap":20 print("搞毛线ldap,不会。。。。")21 22 return wrapper23 return outer_wrapper24 25 def index():26 print("welcome to index page")27 @auth(auth_type="local") # home = wrapper()28 def home():29 print("welcome to home page")30 return "from home"31 32 @auth(auth_type="ldap")33 def bbs():34 print("welcome to bbs page")35 36 index()37 print(home()) #wrapper()38 bbs()
Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in Python-Dekoratoren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



MySQL hat eine kostenlose Community -Version und eine kostenpflichtige Enterprise -Version. Die Community -Version kann kostenlos verwendet und geändert werden, die Unterstützung ist jedoch begrenzt und für Anwendungen mit geringen Stabilitätsanforderungen und starken technischen Funktionen geeignet. Die Enterprise Edition bietet umfassende kommerzielle Unterstützung für Anwendungen, die eine stabile, zuverlässige Hochleistungsdatenbank erfordern und bereit sind, Unterstützung zu bezahlen. Zu den Faktoren, die bei der Auswahl einer Version berücksichtigt werden, gehören Kritikalität, Budgetierung und technische Fähigkeiten von Anwendungen. Es gibt keine perfekte Option, nur die am besten geeignete Option, und Sie müssen die spezifische Situation sorgfältig auswählen.

Hadidb: Eine leichte, hochrangige skalierbare Python-Datenbank Hadidb (HadIDB) ist eine leichte Datenbank in Python mit einem hohen Maß an Skalierbarkeit. Installieren Sie HadIDB mithilfe der PIP -Installation: PipinstallHadIDB -Benutzerverwaltung erstellen Benutzer: createUser (), um einen neuen Benutzer zu erstellen. Die Authentication () -Methode authentifiziert die Identität des Benutzers. fromHadidb.operationImportUseruser_obj = user ("admin", "admin") user_obj.

Es ist unmöglich, das MongoDB -Passwort direkt über Navicat anzuzeigen, da es als Hash -Werte gespeichert ist. So rufen Sie verlorene Passwörter ab: 1. Passwörter zurücksetzen; 2. Überprüfen Sie die Konfigurationsdateien (können Hash -Werte enthalten). 3. Überprüfen Sie Codes (May Hardcode -Passwörter).

MySQL kann ohne Netzwerkverbindungen für die grundlegende Datenspeicherung und -verwaltung ausgeführt werden. Für die Interaktion mit anderen Systemen, Remotezugriff oder Verwendung erweiterte Funktionen wie Replikation und Clustering ist jedoch eine Netzwerkverbindung erforderlich. Darüber hinaus sind Sicherheitsmaßnahmen (wie Firewalls), Leistungsoptimierung (Wählen Sie die richtige Netzwerkverbindung) und die Datensicherung für die Verbindung zum Internet von entscheidender Bedeutung.

Die MySQL-Datenbankleistung Optimierungshandbuch In ressourcenintensiven Anwendungen spielt die MySQL-Datenbank eine entscheidende Rolle und ist für die Verwaltung massiver Transaktionen verantwortlich. Mit der Erweiterung der Anwendung werden jedoch die Datenbankleistung Engpässe häufig zu einer Einschränkung. In diesem Artikel werden eine Reihe effektiver Strategien zur Leistungsoptimierung von MySQL -Leistung untersucht, um sicherzustellen, dass Ihre Anwendung unter hohen Lasten effizient und reaktionsschnell bleibt. Wir werden tatsächliche Fälle kombinieren, um eingehende Schlüsseltechnologien wie Indexierung, Abfrageoptimierung, Datenbankdesign und Caching zu erklären. 1. Das Design der Datenbankarchitektur und die optimierte Datenbankarchitektur sind der Eckpfeiler der MySQL -Leistungsoptimierung. Hier sind einige Kernprinzipien: Die Auswahl des richtigen Datentyps und die Auswahl des kleinsten Datentyps, der den Anforderungen entspricht, kann nicht nur Speicherplatz speichern, sondern auch die Datenverarbeitungsgeschwindigkeit verbessern.

MySQL Workbench kann eine Verbindung zu MariADB herstellen, vorausgesetzt, die Konfiguration ist korrekt. Wählen Sie zuerst "Mariadb" als Anschlusstyp. Stellen Sie in der Verbindungskonfiguration Host, Port, Benutzer, Kennwort und Datenbank korrekt ein. Überprüfen Sie beim Testen der Verbindung, ob der Mariadb -Dienst gestartet wird, ob der Benutzername und das Passwort korrekt sind, ob die Portnummer korrekt ist, ob die Firewall Verbindungen zulässt und ob die Datenbank vorhanden ist. Verwenden Sie in fortschrittlicher Verwendung die Verbindungspooling -Technologie, um die Leistung zu optimieren. Zu den häufigen Fehlern gehören unzureichende Berechtigungen, Probleme mit Netzwerkverbindung usw. Bei Debugging -Fehlern, sorgfältige Analyse von Fehlerinformationen und verwenden Sie Debugging -Tools. Optimierung der Netzwerkkonfiguration kann die Leistung verbessern

Die MySQL -Verbindung kann auf die folgenden Gründe liegen: MySQL -Dienst wird nicht gestartet, die Firewall fängt die Verbindung ab, die Portnummer ist falsch, der Benutzername oder das Kennwort ist falsch, die Höradresse in my.cnf ist nicht ordnungsgemäß konfiguriert usw. Die Schritte zur Fehlerbehebung umfassen: 1. Überprüfen Sie, ob der MySQL -Dienst ausgeführt wird. 2. Passen Sie die Firewall -Einstellungen an, damit MySQL Port 3306 anhören kann. 3. Bestätigen Sie, dass die Portnummer mit der tatsächlichen Portnummer übereinstimmt. 4. Überprüfen Sie, ob der Benutzername und das Passwort korrekt sind. 5. Stellen Sie sicher, dass die Einstellungen für die Bindungsadresse in my.cnf korrekt sind.

Für Produktionsumgebungen ist in der Regel ein Server erforderlich, um MySQL auszuführen, aus Gründen, einschließlich Leistung, Zuverlässigkeit, Sicherheit und Skalierbarkeit. Server haben normalerweise leistungsstärkere Hardware, redundante Konfigurationen und strengere Sicherheitsmaßnahmen. Bei kleinen Anwendungen mit niedriger Last kann MySQL auf lokalen Maschinen ausgeführt werden, aber Ressourcenverbrauch, Sicherheitsrisiken und Wartungskosten müssen sorgfältig berücksichtigt werden. Für eine größere Zuverlässigkeit und Sicherheit sollte MySQL auf Cloud oder anderen Servern bereitgestellt werden. Die Auswahl der entsprechenden Serverkonfiguration erfordert eine Bewertung basierend auf Anwendungslast und Datenvolumen.
