Même si vous connaissez les spécifications linguistiques, il y a une erreur que vous finirez par le faire. J'ai résumé par inadvertance les erreurs que j'ai tendance à faire.
En Python, si vous écrivez une chaîne littérale successivement, elle sera automatiquement concaténée.
>>> "aaa" "bbb"
'aaabbb'
Grâce à cela, si vous oubliez d'ajouter une virgule lors de la définition d'un tableau de littéraux de chaîne, vous risquez de ne pas le remarquer car cela ne provoque pas d'erreur.
>>> [
... 1 #Si vous oubliez d'ajouter une virgule autre qu'une chaîne de caractères, une erreur se produira.
... 2
File "<stdin>", line 3
2
^
SyntaxError: invalid syntax
>>> [
... "a" #Pour les chaînes littérales, oublier d'ajouter une virgule ne provoque pas d'erreur
... "b",
... "c"
... ]
['ab', 'c']
C'est une erreur que les débutants ont tendance à faire. Par exemple, lorsque vous créez une liste et l'assignez à une variable, vous lui donnez le nom de variable «list».
>>> list((1, 2, 3))
[1, 2, 3]
>>> list = list((1, 2, 3))
>>> list = list((1, 2, 3))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not callable
Si vous donnez le nom de variable «list», vous ne pourrez plus appeler «list ()» après cela.
Il est courant de créer un fichier nommé test. *
Lorsque vous voulez faire quelque chose un peu.
Mais vous ne pouvez pas faire cela avec Python. Parce qu'il y a un test
dans le module standard, les noms seront en conflit.
Veillez à ne pas utiliser le même nom, car de nombreux modules Python standard ont des noms très communs autres que test
.
Ne faites pas test.py en Python! --Qiita [python] 10 vrais pièges de Python qui sont trop détaillés pour être véhiculés | My Koiwa Hotchkiss
Les taples sont définis en les séparant par des virgules, comme «x, y, z», mais lorsqu'il y a un élément, ils doivent être suivis d'une virgule, comme «x».
>>> 1, 2, 3
(1, 2, 3)
>>> 1,
(1,)
Lorsque vous utilisez réellement un taple, il est souvent utilisé en le mettant entre ()
comme (x, y, z)
en raison de la structure de l'instruction, mais à partir de là, il est inclus dans ()
. Par exemple, si vous pensez que ce sera un taple, vous ferez une erreur en oubliant d'ajouter une virgule lorsqu'il n'y a qu'un seul élément.
>>> (1, 2, 3) # ()Si vous pensez que ce sera un taple si vous l'entourez de...
(1, 2, 3)
>>> (1) #Oubliez de mettre une virgule quand il n'y a qu'un seul élément
1
Pour éviter cela, prenez l'habitude de mettre une virgule après le dernier élément, même s'il y a plusieurs éléments.
>>> (1, 2, 3,) #Si vous avez l'habitude de mettre une virgule après le dernier élément...
(1, 2, 3)
>>> (1,) #Ne vous y trompez pas quand il n'y a qu'un seul élément
(1,)
Certains modules standard ont des classes et des fonctions portant le même nom que le nom du module. Par exemple, «datetime.datetime» ou «pprint.pprint».
Bien sûr, la façon dont vous écrivez le code à appeler est différente lorsque vous importez un module et lorsque vous importez une classe interne, mais il est facile de se tromper si le module et la classe ont le même nom.
Surtout lorsque l'instruction d'importation est insérée par la fonction de complétion de l'EDI, la classe interne peut être importée même si le module était destiné à être importé, et vice versa.
Lors de l'importation de modules
import datetime
datetime.datetime.now()
Lors de l'importation d'une classe
from datetime import datetime
datetime.now()
En Python, ʻobject.nameest utilisé pour faire référence à un attribut d'objet, et ʻobject ["name"]
est utilisé pour faire référence à un élément de dictionnaire.
En JavaScript, ʻobject.nameet ʻobject ["name"]
ont le même résultat, mais en Python ils se comportent clairement différemment.
Voir les attributs des objets
>>> class A(object):
... def __init__(self):
... self.attr1 = 123
...
>>> a = A()
>>> a.attr1
123
>>> a["attr1"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'A' object is not subscriptable
Se référer aux éléments du dictionnaire
>>> b = {"key1": 123}
>>> b["key1"]
123
>>> b.key1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'key1'
La méthode de vérification d'existence est également différente: l'attribut de l'objet est hasattr (object," name ")
, et l'élément du dictionnaire est "name" in object`.
Notez que l'écriture d'un contrôle d'existence d'attribut pour un objet dictionnaire ne provoque pas d'erreur.
Vérifier l'existence d'attributs d'objet
>>> a = A()
>>> "attr1" in a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: argument of type 'A' is not iterable
>>> hasattr(a, "attr1")
True
Vérifier l'existence d'éléments de dictionnaire
>>> b = {"key1": 123}
>>> "key1" in b
True
>>> hasattr(b, "key1") #Aucune exception ne se produit!
False
En Python, les variables d'instance et les variables de classe sont créées comme suit.
class A(object):
val1 = [1, 2, 3] #Variable de classe
def __init__(self):
self.val2 = [4, 5, 6] #Variable d'instance
L'écriture de variables de classe en Python est similaire à la définition de variables d'instance dans un langage à typage statique.
De plus, vous pouvez accéder aux variables de classe avec self.name
de la même manière que les variables d'instance, vous pouvez donc penser que vous manipulez des variables d'instance, mais il s'agissait en fait de variables de classe.
>>> class A(object):
... val = [1, 2, 3] #J'avais l'intention de créer une variable d'instance
...
>>> a = A()
>>> b = A()
>>> a.val #Accessible comme une variable d'instance
[1, 2, 3]
>>> b.val
[1, 2, 3]
>>> a.val.append(10) #Je pense que je manipule la variable d'instance de l'objet a...
>>> a.val
[1, 2, 3, 10]
>>> b.val #L'objet b a également changé...
[1, 2, 3, 10]
>>> A.val #Je manipulais en fait des variables de classe
[1, 2, 3, 10]
En Python, vous ne pouvez pas utiliser le même nom pour une méthode d'instance et une variable d'instance en même temps. Étant donné qu'une fonction est un objet de première classe et un langage typé dynamiquement, il n'est pas surprenant que si vous affectez une valeur à une variable d'instance avec le même nom que la méthode d'instance, la méthode d'instance sera écrasée par la valeur. Je vais.
>>> class A(object):
... def hoge(self, x):
... self.hoge = x #J'ai l'intention de le définir dans une variable d'instance hoge qui est différente de la méthode hoge
...
>>> a = A()
>>> a.hoge(123) #À ce stade, un.hoge est une méthode donc vous pouvez l'appeler
>>> a.hoge(456) #À ce stade, un.hoge est un nombre(123)Je ne peux pas l'appeler parce que c'est
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
) --Lorsque vous faites référence à
self.hoge, la variable de classe est référencée s'il n'y a pas de variable d'instance. --Lorsque vous écrivez une instruction d'affectation avec
self.hoge = 123, elle est affectée à la variable d'instance
hoge indépendamment de la présence ou de l'absence de la variable de classe
hoge`.En Python, les méthodes de classe et les méthodes statiques sont définies avec des décorateurs.
class A(object):
@classmethod
def hoge(cls, x):
pass
@staticmethod
def meke(x):
pass
De plus, les méthodes de classe et les méthodes statiques peuvent être remplacées dans les sous-classes ainsi que les méthodes d'instance. Dans ce cas, la méthode remplacée doit avoir le même décorateur que la superclasse. (À moins que vous n'osiez changer les caractéristiques de la méthode)
class B(A):
@classmethod #Également requis lors du remplacement
def hoge(cls, x):
pass
@staticmethod #Également requis lors du remplacement
def meke(x):
pass
Si vous oubliez d'ajouter le décorateur lors du remplacement, cela ne causera pas d'erreur en soi, mais soyez prudent car la valeur du premier argument changera en objet d'instance (self).
Si vous le faites avec PyCharm complément, il ne prendra pas le relais du décorateur, donc je fais parfois des erreurs.
La valeur de l'argument par défaut de la fonction n'est évaluée qu'une seule fois lorsque la fonction est définie. Il n'est pas évalué à chaque fois que vous appelez une fonction.
>>> class A(object):
... def __init__(self):
... print("A()A été appelé!")
...
>>> def hoge(a=A()):
... print("hoge()A été appelé!")
...
A()A été appelé!#Les arguments par défaut sont évalués immédiatement après la définition de hoge
>>> hoge()
hoge()A été appelé!#Les arguments par défaut ne sont pas évalués lorsque hoge est appelé
>>> hoge()
hoge()A été appelé!
Pour cette raison, l'utilisation des valeurs suivantes comme arguments par défaut entraînera des résultats décevants.
--Objets tels que des tableaux et des dictionnaires
```pycon
def append(v, l=[]): ... l.append(v) ... return l ...
append(1) #Ajouter 1 au tableau vide [1]
append(2) #Ajouter 2 au tableau vide...Devrait être... [1, 2]
--Valeurs dynamiques telles que la date et l'heure actuelles
```pycon
>>> from datetime import datetime
>>> import time
>>> def printtime(t=datetime.now()):
... print(t)
...
>>> printtime()
2016-02-07 12:30:00.000000
>>> time.sleep(5) #Attendez 5 secondes
>>> printtime()
2016-02-07 12:30:00.000000 #Le temps s'est arrêté! ??
Pour éviter cela, définissez la valeur par défaut sur Aucun et définissez la valeur d'origine dans la fonction.
>>> def append(v, l=None):
... if not l:
... l = []
... l.append(v)
... return l
...
>>> append(1)
[1]
>>> append(2)
[2]
Les chaînes Python agissent comme des itérateurs de caractères.
Par conséquent, vous ne le remarquerez peut-être pas même si vous oubliez d'ajouter []
lorsque l'argument appelle la fonction du tableau.
>>> def print_items(items):
... for i, x in enumerate(items):
... print("[%d]=%s" % (i, x))
...
>>> print_items([1, 2])
[0]=1
[1]=2
>>> print_items(["ab"]) #Pour être correct, écris comme ça...
[0]=ab
>>> print_items("ab") # []Si vous oubliez de le mettre, ce sera comme ça.
[0]=a
[1]=b
>>> print_items(["a"]) #Mais si c'est une lettre...
[0]=a
>>> print_items("a") # []Même si vous oubliez de mettre, le résultat est le même, donc vous ne remarquez pas
[0]=a
Recommended Posts