与C/C++、Java等编译型语言相比,Python语言显得更简洁优雅,敲起代码来更是一个爽字了得。作为初学者,很多朋友可能受前者编译型语言的影响,会在刚入门时有不少错误出现,但这些错误都是容易通过自己编译调试或者上网搜索/求助找到解决方法的。笔者基于自身经验,从注释与数据类型使用等六个方面总结梳理了初学者易犯的错误,提醒自己避开这些踩过的坑,同时也供读者借鉴。
注释与数据类型使用
1.Python中的注释没有“//”,这是C/C++中的单行注释!合法的注释形式有三种:# 要注释的内容(单行注释)
、'''要注释的内容(多行注释)'''
、"""要注释的内容(多行注释)"""
。
2.Python中的变量类型是可变的,不像C/C++!比如:用str()
函数将数值/列表类型转换成字符串类型等。
3.列表的乘法是元素的复制叠加,不是元素的乘法运算![1,2,3] * 2
得到的是[1,2,3,1,2,3]
!
4.列表的append方法改变了列表本身,无返回值(返回None)!相反,字符串的strip等方法不会改变字符串本身(字符串是不可变类型),会返回改变后的新字符串!
t = [1, 2, 3]
print(t.append(4)) # 输出None
s = "--Python--"
s.strip('-')
print(s) # 输出还是“--Python--”
5.字符串切片判断错误
s = 'Python'
print(s[-1::]) # 输出的是“n”
分支判断/循环语句
1.逻辑表达式的结果一定是布尔值(两种类型:True
和False
),if后面不一定要跟逻辑表达式,也可直接跟布尔值。
2.在判断语句中,要分清数字型字符串和整型数据!下面的代码进入了死循环:
while True:
user = input('请输入你的用户名:')
pwd = input('请输入密码:')
if user == 'admin' and pwd == 123456:
print('登录成功!')
break
3.判断是否是None,对于单个变量被赋值的时候,== 和 is 没有区别,但是语法规范建议用 is 判断。== 运算符主要是用来比较两个操作对象之间是否相等,比较的是值(Value)相等,默认会调用对象的__eq__()方法;is 主要是用来比较两个操作对象的引用是否是同一个,指向的是否是同一块内存,比较的是对象的id。测试代码如下:
a = [1]
b = [1]
c = a
# 获取a,b,c在内存中的一个标识
print(id(a)) # 46495496
print(id(b)) # 46494984
print(id(c)) # 46495496
print(a == b) # True
print(a is b) # False
print(a == c) # True
print(a is c) # True
d = None
print(d == None) # True
print(d is None) # True
class Foo:
def __eq__(self, other):
print("其实都是我判断的")
return True
a = Foo()
b = None
print(id(a)) # 48741456
print(id(b)) # 8791246712032
print(id(None)) # 8791246712032
print(a == b) # True 打印:其实都是我判断的
print(a is None) # False
print(a is b) # False
print(a == None) # True 打印:其实都是我判断的
4.三元判断中可加括号增加判断操作,比如:
c, d = 5, 5
print('c大于d') if c > d else (print('c小于d') if c < d else print('c等于d')) # 打印:“c等于d”
5.指定循环次数写while循环时,计数器变量要在循环体中有变化(+1或-1),否则程序死循环,比如:
nums = [11, 22, 33, 44, 55]
i = 0
while i < len(nums):
print(f"{i}-> {nums[i]}")
函数定义与使用
1.函数参数中有缺省参数时,判断容易错误,如:
def print_info(name, *args, gender=True): # 函数缺省参数必须放在位置参数之后
print(name, args, gender)
print_info("tom", 66, 77, 88, False) # 打印:tom (66, 77, 88, False) True
2.lambda **kwargs: 1 调用此匿名函数可输入任意键值对参数,输出都是1。
f = lambda **kwargs: 1
print(f(a='d', b=4)) # 1
3.列表等可变数据类型作函数参数时容易出错,比如:
li = [1,2,3]
print(li) # [1, 2, 3]
def md(li):
li.append(7) # 影响全局变量!
li = [1,2] # 这是是局部变量,不影响全局变量!
print(li) # 打印局部变量!
md(li) # [1, 2]
print(li) # [1, 2, 3, 7]
模块导入与使用
1.import自己写的模块而该模块又和python内置模块重名时,系统优先使用自己的模块,但time库例外!建议命名时还是不要跟内置模块重名!
# random.py
def myrand():
print("my random")
# time.py
def timep():
print("my time")
# test.py
import time, random
random.myrand() # 打印:"my random"
time.timep() # AttributeError!
2.导入os库,删除文件夹可用 os.rmdir() ,不要用 os.remove()!
3.创建新文件夹并在其中创建新文件时,使用 os.mkdir() 后要立刻 os.chdir(),否则仍然在当前文件夹目录下而不会到新文件夹中去!
4.如果要删除目录中的所有指定后缀名文件(包括子目录中的),要用递归!导入os库:
os.path.isdir() 返回是否存在此目录;
os.listdir() 返回当前目录下的文件结构;
os.path.join() 返回绝对路径,第一个参数是原始目录,第二个参数是新的文件或者文件夹的名字;
os.path.isfile() 判断当前的路径是文件还是文件夹;
os.remove() 可用来删除一个文件。
类与对象
1.类的初始化魔术方法是__init__,不是__int__!
class A(object):
def __int__(self, pb=10):
self.__data = 100
self.public = pb
a = A(10) # TypeError: A() takes no arguments
2.派生类的初始化魔术方法有三种合法形式:
class Student(Person):
def __init__(self, name, age):
super().__init__(name,age)
# super(Student, self).__init__(name,age)
# Person.__init__(self, name, age)
异常处理
1.异常处理语句中的 finally 是都会执行到的,无论有没有捕捉到指定异常!
# 下面的程序先打印:Program is running here! 再报错:
# TypeError: unsupported operand type(s) for /: 'int' and 'str'
try:
a = 1 / '1'
except ZeroDivisionError:
print("Division is 0 ,Wrong!")
finally:
print("Program is running here!")
2.异常处理中 except 后如果加上跟 Exception(as e),可能出现不能捕获异常的情况,因为有些异常(比如下面出现的KeyboardInterrupt
)不属于Exception类!
import time
try:
f = open('p.txt', 'r')
try:
while True:
content = f.read(1)
if len(content) == 0:
break
print(content)
time.sleep(1)
except Exception: # 下一行代码不会执行!但把Exception去掉就可以。
# 如果人为中止这个程序(按下 Ctrl + C 键),则弹出提示信息
print('文件读取未完成,人为中断了以上代码的执行')
else:
print('文件读取完成')
finally:
f.close()
except: # 人为中止,下一行代码会执行!
print('访问的文件不存在')
更多详情请参考: Python异常及处理方法总结
3.PyCharm中的输出终端(4:Run)和命令终端 Terminal 有区别,Ctrl + C 强制终止程序运行的功能只能在Terminal中才出现,比如上面第2点中的情形。
更多详情请参考: Pycharm中Run窗口、Terminal窗口、Python Console窗口的区别及其切换方法
以上。