关于Python中的基础问题与重点语法分析
⽬录
⾝为⼀个python⼩⽩,在不懈的学习了快两个⽉python后,已经基本学完了python的基础语法,在学习中也遇到了很多坑,现在我希望把我遇到的坑分享⼀下,也是关于⼀些基础问题,希望对刚开始学习的⼩伙伴可以有所帮助。同时⾥⾯也有⼏个python⾥的⾼级语法和难理解的概念,这⾥⾯本⾝也包含我⾃⼰不理解的⼀些点,我抱着尝试的⼼去讲⼀下,要是对⾥⾯的⼀些代码或者专业词汇描述有错或者讲错的话,还请专业⼈⼠指正。
⼀、pycharm的使⽤问题
相信很多⼈在学习的时候都下载了pycharm,⾝为python的⼀个集成开发环境,pycham我觉得编程环境是最好的。除此之外我也试过vs vscode等,但我觉得都没有pycharm好⽤。
1、在pycharm上我建议下载tabnine的代码补全和(根据个⼈需要,要是英语特别好或者后期其实不⽤,甚⾄⽤起来会很别扭)
2、pycharm不同于IDLE,IDLE上使⽤print或者直接敲回车都可以实现输出,但是pycharm上必须是要加⼀个print的,例如这样⼀个查索引值的代码和布尔类型,在IDLE中直接敲回车就可以实现,但是pych
arm中的print必不可少
a=["1","2"]
print("1" in a)
print(a.index("1"))
3、pycharm最⼈性话的设计可能是每⽇⼩技巧了,他会每天根据你敲的代码来给你⼀点⼩技巧使你更⽅便,但是这在之后也也是英⽂显⽰,但是还是建议直接耐⼼翻译去看⼀下。
⼆、⾸⾏缩进
这是我碰到的最难受的⼀个点了,有的时候你⾸⾏缩进错了pycharm并不会报错,但是会让你得到不是你想要的东西,有的时候也会⼤⽚的报错。
⽽我总结了⼀下,主要就是逻辑问题,写程序时候的逻辑不能错,这件事⼲完该⼲什么,是并列还是包含,只要把本质弄清楚,就不会错
1、if else elif 这是最基础的但也是在逻辑上最容易出错的,我就从我直接做的⼀些作业来说,例如我在之前学完循环语句和条件语句做的⼀个⼩作业,要让打印⼀个购物车的程序,循环打印商品列表
product=[["iphone",111],["xiaomi",222],["huawei",333]]
shopping_cart=[]
while True:
print("-----商品列表--------")
for index,i in enumerate(product):
print("%s.%s %s"%(index,i[0],i[1] ))
choice = input("输⼊你想买的东西的编号:")
if choice.isdigit():
choice=int(choice)
shopping_cart.append(product[choice])
print("Add product %s into shopping cart."%(product[choice]))
elif choice=="q":
print("-----你已经购买以下商品-----")
for index,p in enumerate(shopping_cart):
print("%s. %s %s" % (index,i[0],i[1]))
尤其是中间,在中间开始循环之后,利⽤for循环和enumerat函数将商品产⽣出索引值以后,if语句跟for循环是并列的,⽽不能将if和elif 缩进进去,这样才能使if语句有效,且在elif语句输⼊q退出时,另⼀for也必须在elif语句⾥⾯这样才能退出并打印已经加⼊的商品列表
2、函数类与⾯向对象的缩进,这两者中的语法显然⽐缩进重要,但是在这⾥也提⼀下,以这样的⼀段嵌套为例
age=19
def k1():
age = 73
print(age)
def k2():
print(age)
k2()
k1()
调⽤参数位置的不同也能影响输出的结果,类与⾯向对象与函数相似,在调⽤与实例化的时候也需要注意。
注:主要在函数以及⾯向对象中,会出现嵌套函数以及多态问题,进⽽对逻辑有了更⼤的要求。
三、深浅copy
这算是python⾥⾯⽐较难理解的⼀个点,容易在考试⾥⾯出到,我们先从这样⼀段代码然后逐步加深理解
>>>a=1
>>>b=a
>>>a=2
>>>b
1
>>>id(a)
>>>id(b)
在这段代码⾥,你要是输出b的值你会发现会输出1,因为在b=a以后,b指向了1,⽽并不是指向a,所以b并不会跟随a改变,可以⽤最后两⾏代码来验证⼀下他们的内存地址(下⾯的代码相当于我在IDLE⾥⾯写的)
现在我们在列表⾥来看⼀下这段代码
>>>n1=["hu","wang","iphone",1,2]
>>>n2=n1
>>>n2
["hu","wang","iphone",1,2]
>>>n1[2]="huawei"
>>>n1=["hu","wang","weawei",1,2]
>>>n2
⼤家想⼀想,我此时输出n2会发⽣什么,按照上⾯的理解,n2是不会跟着n1改变的,但是他输出的结果和改变后的n1是⼀样的,这是为什么,就像我把⼀个东西放到杯⼦⾥⾯,每⼀个东西就是⼀个内存地址,现在n2直接指向了n1的内存地址,相当于n2,n1完全相同,对这两个列表进⾏增删查改,这两个列表也仍然相同
但是如何将这两个列表独⽴呢,这是⽤copy可以实现
>>>n1=["hu","wang","iphone",1,2]
>>>py()
>>>n1,n2
>>>(['hu', 'wang', 'iphone', 1, 2], ['hu', 'wang', 'iphone', 1, 2])
⽤两种⽅法可以检验⼀下是否独⽴,检验内存地址和改值
>>>n1=["hu","wang","iphone",1,2]
>>>py()
>>>n1,n2
>>>(['hu', 'wang', 'iphone', 1, 2], ['hu', 'wang', 'iphone', 1, 2])
>>>id(n1)
2998395112000
>>>id(n2)
2998395300480
>>>n1[1]=2
>>>n1
['hu', 2, 'iphone', 1, 2]
>>>n2
['hu', 'wang', 'iphone', 1, 2]
此时会发现,内存地址并不⼀样并且修改n1后n2也不变,但是这样做⼜会有⼀个新问题,⽐如这样
>>>n1[1]=2
>>>n1
['hu', 2, 'iphone', 1, 2]
>>>n2
['hu', 'wang', 'iphone', 1, 2]
python新手代码错了应该怎么改>>>n1.append(["3",3])
>>>n1
['hu', 2, 'iphone', 1, 2,["3",3]]
>>>n1[-1][0]="huhu"
>>>n1
['hu', 2, 'iphone', 1, 2,["huhu",3]]
>>>n2
['hu','wang', 'iphone', 1, 2,["huhu",3]]
⼤家发现了什么,我在n1这个列表⾥加了⼀个列表,不是说已经独⽴了吗,我在修改了n1这个列表⾥⾯的列表,n2也跟着改了。这是为什么,我们所说的独⽴,是这个列表⾥⾯的元素独⽴了,即是列表⾥⾯的列表独⽴,为什么⼦列表⾥⾯的元素会变,因为⼦列表的元素都指向⼀个内存地址即这个⼦列表。
综上所述
以上都是浅层次的独⽴了列表,所有叫浅copy,但是如何深copy呢,这是需要导⼊⼀个库,当我们导⼊了copy库以后,便可以完全实现深copy了。
import copy
>>>n1=['hu', 2, 'iphone', 1, 2,["3",3]]
>>>py()
>>>n2
['hu', 2, 'iphone', 1, 2,["3",3]]
>>>n1[-1][0]="huhu"
>>>n1
['hu', 2, 'iphone', 1, 2,["huhu",3]]
>>>n2
['hu','wang', 'iphone', 1, 2,["3",3]]
四、字符编码
python中的字符编码真的好复杂好复杂,甚⾄python2和python3也有不同,这⾥⾯也涉及到有的时候为什么你输出的结果变成了乱码,我其实也不知道我现在到底理解了没有,但是先讲⼀下,看看我到底能不能把这个最基本的讲清楚
1、什么是字符编码
学计算机的朋友们应该都知道,计算机只能通过0和1来识别我们的语⾔,所以字符编码就是将我们的语⾔全部转为⼆进制来让计算机去理解
2、⼀些常见的字符编码
①ASCII
这是美国⼈发明的包含了最基本的128个字符的编码表,通过这些使计算机可以了解我们的语⾔,但是这⾥⾯是英⽂字符啊,中国⼈要是想⽤怎么办,于是Unicode诞⽣了
②unicode
Unicode⼜被称为统⼀码、万国码;它为每种语⾔中的每个字符设定了统⼀并且唯⼀的⼆进制编码,以满⾜跨语⾔、跨平台进⾏⽂本转换、处理的要求。
③GB2312与GBK
中国国家标准总局1980年发布《信息交换⽤汉字编码字符集》提出了GB2312编码,⽤于解决汉字处理的问题。1995年⼜颁布了《汉字编码扩展规范》(GBK)。这样就解决了我们国家的编码问题。
④UTF :UTF-8,UTF-16 UTF-32
既然unicode这么好⽤,为什么不全世界⼀直⽤unicode呢,unicode存在这样的⼀个问题,使⽤unicode来表⽰⼀个字符,⾄少占两个字节,⽽ASCII码只需要⼀个,这样会导致浪费内存空间,所以UTF出现了,UTF就是为unicode编码设计的⼀种在存储和传输时节省空间的编码⽅案,可以理解为对unicode的⼀种压缩,最常⽤的为UTF-8
UTF-8使⽤1、2、3、4个字节表⽰所有字符,⽆法满⾜则增加⼀个字节
3、python2与python3的字符编码
python3字符串默认unicode ⽽⽂件默认编码是UTF-8,python2中,⽂件编码和字符串编码中都为ASCII,若⽂件头声明gbk,则字符串编码为gbk
4、编码在windows上的显⽰
这⾥涉及到你写的程序在终端上的运⾏,我也还没有学习只是简单了听了⼀点,例如windows智能显⽰unicode和gbk,否则会变成乱码。
5、字符编码的转换
你可以通过以下代码来进⾏字符编码的转换
>>>s="hu"
>>>s2=1.decode("utf-8")
总结:我对于字符编码的理解也只是这些基础知识,这⾥⾯有的东西还涉及到终端⾥的输出 与unicode编码的详解我都不拿出来说了,希望后续可以有⼤佬来进⾏详解。
五、闭包函数和装饰器
关于闭包函数和装饰器,这是我讲的唯⼀⼀个⾼级语法,我看了视频⾥⾯说这也是在⾯试⾥⽐较容易出到的问题,⾸先何为装饰器,以我的理解,就是升级你的函数功能,但是,升级函数的⽅法⼜很多种,你可以定义多个函数,可以多次调⽤函数,但是、、、、
第⼀,有的时候你的代码实现了功能但是却会违反⼀些原则,例如“开放-封闭”原则:
开放:已实现的功能代码块不能被修改
封闭:对现有的功能进⾏拓展开发
第⼆,软件开发需要的是多个团队的运营和调试,包含成千上万的代码,你这边实现了⾃⼰的模块,下⼀组的⼈呢,或许之后的代码就需要重复修改⼏千次甚⾄⼏万次或者直接报错。现在我以这样的⼀个功能来⼀步步进⾏讲解
⽐如这样,你的⽼板要让你将查数字和记录时间整合到⼀起,可能你会写出这样⼀段代码(这⾥引⽤了b站up主‘嘉然今晚吃⼦’的讲解视频,想学习的同学也可以去看⼀下)
import time
def kprint_odds():
start_time=time.perf_counter()
for i in range(100):
if i in range(100):
print(i)
end_time=time.perf_counter()
print("it takes {} s to find all the odds".format(end_time-start_time)
if __name__="__main__"
print_odds()
这⼀个函数你会发现你成功的实现了功能,但是你会发现⼀个函数两个辅助功能,有的代码⾥⾯或许不⽌两个辅助功能,万⼀出错修改⾮常⿇烦甚⾄影响了主要功能,代码函数⼀多,这样写函数⼏乎就是⼀个灾难,于是我们可以这样修改
import time
def count_time(func):
start_time=time.perf_counter()
func()
end_time=time.perf_counter()
print("it takes {} s to find all the odds".format(end_time-start_time)
def print_odds():
for i in range(100):
if i%2 == 1:
print(i)
id __name__="__main__":
count_time(print_odds)
这样定义两个函数便可以减少错误,但是这样的写法仍有⼀个缺点,最后是通过在辅助函数⾥传⼊主要函数进⾏运⾏,语法上可⾏,在可读性上不好,给读者显⽰的应该是直接显⽰主要函数,辅助函数应该被隐藏起来,于是我们就引⼊闭包函数。
闭包函数:⼀个函数的参数和返回值都是函数
注:闭包本质上是⼀个函数
闭包函数的传⼊参数和返回值也都是函数
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论