Even if you know the language specifications, there is a mistake that you will end up doing it. I inadvertently summarized the mistakes that I tend to make.
In Python, continuous writing of string literals will automatically concatenate them.
>>> "aaa" "bbb"
'aaabbb'
Thanks to this, if you forget to add a comma when defining an array of string literals, you may not notice it because it does not cause an error.
>>> [
... 1 #If you forget to add a comma other than a character string, an error will occur.
... 2
File "<stdin>", line 3
2
^
SyntaxError: invalid syntax
>>> [
... "a" #For string literals, forgetting to add a comma does not cause an error
... "b",
... "c"
... ]
['ab', 'c']
This is a mistake that beginners tend to make.
For example, when you create a list and assign it to a variable, you give it the variable name 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
If you give the variable name list
, you will not be able to calllist ()
after that.
--Built-in functions -Built-in type
It's common to create a file named test. *
When you want to do some quick confirmation.
But you can't do this in Python. Because there is a test
in the standard module, the names will conflict.
Be careful not to use the same name, as many standard Python modules have very common names other than test
.
Don't make test.py in Python! --Qiita [python] 10 real pitfalls of Python that are too detailed to convey | My Koiwa stapler
Tuples are defined by separating them with commas, such as x, y, z
, but when there is one element, they must be followed by a comma, such asx,
.
>>> 1, 2, 3
(1, 2, 3)
>>> 1,
(1,)
When actually using tuples, due to the structure of the sentence, it is often used by enclosing it in ()
like (x, y, z)
, but for this reason it is enclosed in ()
For example, if you think that it is a tuple, you will make a mistake of forgetting to add a comma when there is only one element.
>>> (1, 2, 3) # ()If you think that it will be a tuple if you surround it with...
(1, 2, 3)
>>> (1) #Forget to put a comma when there is only one element
1
To avoid this, make it a habit to put a comma after the last element even when there are multiple elements.
>>> (1, 2, 3,) #If you have a habit of putting a comma after the last element...
(1, 2, 3)
>>> (1,) #Make no mistake when there is only one element
(1,)
Some standard modules have a class or function with the same name as the module name.
For example, datetime.datetime
or pprint.pprint
.
Of course, the way to write the code to call differs between importing a module and importing an internal class, but it is easy to make a mistake if the module and class have the same name.
Especially when the import statement is inserted by the completion function of the IDE, the module may be imported but the internal class may be imported, and vice versa.
When importing modules
import datetime
datetime.datetime.now()
When importing a class
from datetime import datetime
datetime.now()
In Python, ʻobject.name is used to refer to an object attribute, and ʻobject [" name "]
is used to refer to a dictionary element.
In JavaScript, ʻobject.name and ʻobject [" name "]
have the same result, but in Python they behave clearly differently.
See object attributes
>>> 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
See dictionary elements
>>> 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'
The existence check method is also different: the object attribute is hasattr (object," name ")
, and the dictionary element is " name "in object
.
Note that an error does not occur even if you write an attribute existence check for a dictionary object.
Existence check of object attributes
>>> 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
Check for the existence of dictionary elements
>>> b = {"key1": 123}
>>> "key1" in b
True
>>> hasattr(b, "key1") #No exceptions occur!
False
In Python, instance variables and class variables are created as follows.
class A(object):
val1 = [1, 2, 3] #Class variables
def __init__(self):
self.val2 = [4, 5, 6] #Instance variables
Writing class variables in Python is similar to defining instance variables in a statically typed language.
Also, since you can access class variables with self.name
as well as instance variables, you may think that you are manipulating instance variables, but they were actually class variables.
>>> class A(object):
... val = [1, 2, 3] #I intended to create an instance variable
...
>>> a = A()
>>> b = A()
>>> a.val #Can be accessed like an instance variable
[1, 2, 3]
>>> b.val
[1, 2, 3]
>>> a.val.append(10) #I think I'm manipulating an instance variable of object a...
>>> a.val
[1, 2, 3, 10]
>>> b.val #Object b has also changed...
[1, 2, 3, 10]
>>> A.val #I was actually manipulating class variables
[1, 2, 3, 10]
In Python, you cannot use the same name for an instance method and an instance variable at the same time. Given that a function is a first-class citizen and a dynamically typed language, it's not surprising that if you assign a value to an instance variable with the same name as the instance method, the instance method will be overwritten with the value. I will.
>>> class A(object):
... def hoge(self, x):
... self.hoge = x #I intend to set it in an instance variable hoge that is different from the method hoge
...
>>> a = A()
>>> a.hoge(123) #At this point a.hoge is a method so you can call it
>>> a.hoge(456) #At this point a.hoge is a number(123)I can't call it because it's
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
--The instance method hoge
is kept as a class variable hoge
. (See ʻA.hoge) --When you refer to
self.hoge, the class variable is referenced if there is no instance variable. --When you write an assignment statement with
self.hoge = 123, it is assigned to the instance variable
hogeregardless of the presence or absence of the class variable
hoge`.
In Python, class methods and static methods are defined with decorators.
class A(object):
@classmethod
def hoge(cls, x):
pass
@staticmethod
def meke(x):
pass
In addition, class methods and static methods can be overridden in subclasses as well as instance methods. In that case, the overridden method must have the same decorator as the superclass. (Unless you dare to change the characteristics of the method)
class B(A):
@classmethod #Also needed when overriding
def hoge(cls, x):
pass
@staticmethod #Also needed when overriding
def meke(x):
pass
If you forget to add the decorator when overriding, it will not cause an error by itself, but be careful because the value of the first argument will change to the instance object (self).
If you do it with PyCharm complement, it will not take over to the decorator, so I sometimes make mistakes.
The value of the function's default argument is evaluated only once when the function is defined. It is not evaluated every time you call a function.
>>> class A(object):
... def __init__(self):
... print("A()Was called!")
...
>>> def hoge(a=A()):
... print("hoge()Was called!")
...
A()Was called!#Default arguments are evaluated immediately after defining hoge
>>> hoge()
hoge()Was called!#Default arguments are not evaluated when hoge is called
>>> hoge()
hoge()Was called!
For this reason, using the following values as default arguments will result in disappointing results.
--Objects such as arrays and dictionaries
```pycon
def append(v, l=[]): ... l.append(v) ... return l ...
append(1) #Add 1 to empty array [1]
append(2) #Add 2 to empty array...Should be... [1, 2]
--Dynamic values such as current date and time
```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) #Wait 5 seconds
>>> printtime()
2016-02-07 12:30:00.000000 #Time has stopped! ??
To avoid this, set the default value to None and set the original value in the function.
>>> def append(v, l=None):
... if not l:
... l = []
... l.append(v)
... return l
...
>>> append(1)
[1]
>>> append(2)
[2]
Python strings act as character iterators.
Therefore, you may not notice it even if you forget to add []
when the argument calls the function of the array.
>>> 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"]) #To be correct, write like this...
[0]=ab
>>> print_items("ab") # []If you forget to put on, it will be like this.
[0]=a
[1]=b
>>> print_items(["a"]) #But if it's one letter...
[0]=a
>>> print_items("a") # []Even if you forget to put on, the result is the same, so you do not notice
[0]=a
Recommended Posts