Bei der Verwendung von Python bin ich in letzter Zeit auf einige Fallstricke gestoßen, wie beispielsweise die Verwendung von DatumZeit.datetime.now(), einem variablen -ObjektAls Standardparameter der -Funktion , Modul--Schleifen--Abhängigkeit usw.
Notieren Sie es hier für zukünftige Anfragen und Ergänzungen.
Bei der Verwendung von Funktionen sind häufig Standardparameter beteiligt. Wenn in Python veränderbare Objekte als Standardparameter verwendet werden, können unerwartete Ergebnisse auftreten.
Sehen Sie sich unten ein Beispiel an:
def append_item(a = 1, b = []): b.append(a) print b append_item(a=1) append_item(a=3) append_item(a=5)
Das Ergebnis ist:
[1] [1, 3] [1, 3, 5]
Wie Sie am Ergebnis sehen können, wenn die Funktion append_item später zweimal aufgerufen wird , Funktionsparameterb wird nicht auf [] initialisiert, sondern behält den Wert des vorherigen Funktionsaufrufs bei.
Der Grund für dieses Ergebnis liegt darin, dass in Python der Standardwert eines Funktionsparameters nur einmal initialisiert wird, wenn die Funktion definiert wird.
Sehen wir uns ein Beispiel an, um diese Funktion von Python zu beweisen:
class Test(object): def init(self): print("Init Test") def arg_init(a, b = Test()): print(a) arg_init(1) arg_init(3) arg_init(5)
Das Ergebnis ist:
Init Test 1 3 5
Wie Sie an den Ergebnissen dieses Beispiels sehen können , nur die Testklasse Es wird einmal instanziiert, was bedeutet, dass die Standardparameter nichts mit der Anzahl der Funktionsaufrufe zu tun haben und nur einmal initialisiert werden, wenn die Funktion definiert wird.
Für variable Standardparameter können wir das folgende Muster verwenden, um die oben genannten unerwarteten Ergebnisse zu vermeiden:
def append_item(a = 1, b = None): if b is None: b = [] b.append(a) print b append_item(a=1) append_item(a=3) append_item(a=5)
Das Ergebnis lautet:
[1] [3] [5]
Pythons Bereichsauflösungsreihenfolge ist Lokal, Umschließend, Global, Eingebaut, was bedeutet, dass der Python-Interpreter Variablen< analysiert 🎜>.
global_var = 0 def outer_func(): outer_var = 1 def inner_func(): inner_var = 2 print "global_var is :", global_var print "outer_var is :", outer_var print "inner_var is :", inner_var inner_func() outer_func()
global_var is : 0 outer_var is : 1 inner_var is : 2
num = 0 def var_func(): num = 1 print "num is :", num var_func()
num = 0 def var_func(): print "num is :", num num = 1 var_func()
UnboundLocalError: local variable 'num' referenced before assignment
li = [1, 2, 3] def foo(): li.append(4) print li foo() def bar(): li +=[5] print li bar()
[1, 2, 3, 4] UnboundLocalError: local variable 'li' referenced before assignment
li = [1, 2, 3] def foo(): li.append(4) print li foo() def bar(): global li li +=[5] print li bar()
Auf Klassenattribute kann über den Klassennamen zugegriffen und diese geändert werden. Außerdem kann auf Klassenattribute über die Klasseninstanz zugegriffen und diese geändert werden. Wenn eine Instanz jedoch ein Attribut mit demselben Namen wie die Klasse definiert, wird das Klassenattribut ausgeblendet.
class Student(object): books = ["Python", "JavaScript", "CSS"] def init(self, name, age): self.name = name self.age = age pass wilber = Student("Wilber", 27) print "%s is %d years old" %(wilber.name, wilber.age) print Student.books print wilber.books wilber.books = ["HTML", "AngularJS"] print Student.books print wilber.books del wilber.books print Student.books print wilber.books
das Attribut „books“ löscht Die Wilber-Instanz, wilber.books, entspricht dem Klassenattribut „books“.
Bei der Verwendung vonWilber is 27 years old ['Python', 'JavaScript', 'CSS'] ['Python', 'JavaScript', 'CSS'] ['Python', 'JavaScript', 'CSS'] ['HTML', 'AngularJS'] ['Python', 'JavaScript', 'CSS'] ['Python', 'JavaScript', 'CSS']
in Python-Werten sollten Sie auch auf das Ausblenden von Klassenattributen achten. Für eine Klasse können Sie alle Klassenattribute über das dict-Attribut der Klasse anzeigen.
Wenn Sie über den Klassennamen auf ein Klassenattribut zugreifen, wird zunächst nach dem Diktatattribut der Klasse gesucht. Wenn das Klassenattribut nicht gefunden wird, wird die Suche fortgesetzt für die Elternklasse. Wenn jedoch eine Unterklasse ein Klassenattribut mit demselben Namen wie die übergeordnete Klasse definiert, verdecken die Klassenattribute der Unterklasse die Klassenattribute der übergeordneten Klasse.
Sehen Sie sich ein Beispiel an:
class A(object): count = 1 class B(A): pass class C(A): pass print A.count, B.count, C.count B.count = 2 print A.count, B.count, C.count A.count = 3 print A.count, B.count, C.count print B.dict print C.dict
1 1 1 1 2 1 3 2 3 {'count': 2, 'module': 'main', 'doc': None} {'module': 'main', 'doc': None}
在Python中,tuple是不可变对象,但是这里的不可变指的是tuple这个容器总的元素不可变(确切的说是元素的id),但是元素的值是可以改变的。
tpl = (1, 2, 3, [4, 5, 6]) print id(tpl) print id(tpl[3]) tpl[3].extend([7, 8]) print tpl print id(tpl) print id(tpl[3])
代码结果如下,对于tpl对象,它的每个元素都是不可变的,但是tpl[3]是一个list对象。也就是说,对于这个tpl对象,id(tpl[3])是不可变的,但是tpl[3]确是可变的。
36764576 38639896 (1, 2, 3, [4, 5, 6, 7, 8]) 36764576 38639896
在对Python对象进行赋值的操作中,一定要注意对象的深浅拷贝,一不小心就可能踩坑了。
当使用下面的操作的时候,会产生浅拷贝的效果:
使用切片[:]操作
使用copy模块中的copy()函数
使用copy模块里面的浅拷贝函数copy():
import copy will = ["Will", 28, ["Python", "C#", "JavaScript"]] wilber = copy.copy(will) print id(will) print will print [id(ele) for ele in will] print id(wilber) print wilber print [id(ele) for ele in wilber] will[0] = "Wilber" will[2].append("CSS") print id(will) print will print [id(ele) for ele in will] print id(wilber) print wilber print [id(ele) for ele in wilber]
使用copy模块里面的深拷贝函数deepcopy():
import copy will = ["Will", 28, ["Python", "C#", "JavaScript"]] wilber = copy.deepcopy(will) print id(will) print will print [id(ele) for ele in will] print id(wilber) print wilber print [id(ele) for ele in wilber] will[0] = "Wilber" will[2].append("CSS") print id(will) print will print [id(ele) for ele in will] print id(wilber) print wilber print [id(ele) for ele in wilber]
在Python中使用import导入模块的时候,有的时候会产生模块循环依赖,例如下面的例子,module_x模块和module_y模块相互依赖,运行module_y.py的时候就会产生错误。
# module_x.py import module_y def inc_count(): module_y.count += 1 print module_y.count # module_y.py import module_x count = 10 def run(): module_x.inc_count() run()
其实,在编码的过程中就应当避免循环依赖的情况,或者代码重构的过程中消除循环依赖。
当然,上面的问题也是可以解决的,常用的解决办法就是把引用关系搞清楚,让某个模块在真正需要的时候再导入(一般放到函数里面)。
对于上面的例子,就可以把module_x.py修改为如下形式,在函数内部导入module_y:
# module_x.py def inc_count(): import module_y module_y.count += 1
Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung von Python-Fallen und Vorsichtsmaßnahmen, die häufig in der Entwicklung auftreten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!