目录

一、pycharm的使用问题

二、首行缩进

三、深浅copy

四、字符编码

五、闭包函数和装饰器


  身为一个python小白,在不懈的学习了快两个月python后,已经基本学完了python的基础语法,在学习中也遇到了很多坑,现在我希望把我遇到的坑分享一下,也是关于一些基础问题,希望对刚开始学习的小伙伴可以有所帮助。同时里面也有几个python里的高级语法和难理解的概念,这里面本身也包含我自己不理解的一些点,我抱着尝试的心去讲一下,要是对里面的一些代码或者专业词汇描述有错或者讲错的话,还请专业人士指正

一、pycharm的使用问题

相信很多人在学习的时候都下载了pycharm,身为python的一个集成开发环境,pycham我觉得编程环境是最好的。除此之外我也试过vs vscode等,但我觉得都没有pycharm好用。

1、在pycharm上我建议下载tabnine的代码补全和汉化(汉化根据个人需要,要是英语特别好或者后期其实不用汉化,甚至用起来会很别扭)

2、pycharm不同于IDLE,IDLE上使用print或者直接敲回车都可以实现输出,但是pycharm上必须是要加一个print的,例如这样一个查找索引值的代码和布尔类型,在IDLE中直接敲回车就可以实现,但是pycharm中的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=19def k1():age = 73print(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]
>>>n2=n1.copy()
>>>n1,n2
>>>(['hu', 'wang', 'iphone', 1, 2], ['hu', 'wang', 'iphone', 1, 2])

用两种方法可以检验一下是否独立,检验内存地址和改值

>>>n1=["hu","wang","iphone",1,2]
>>>n2=n1.copy()
>>>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]
>>>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]]
>>>n2=n1.copy()
>>>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)

这样定义两个函数便可以减少错误,但是这样的写法仍有一个缺点,最后是通过在辅助函数里传入主要函数进行运行,语法上可行,在可读性上不好,给读者显示的应该是直接显示主要函数,辅助函数应该被隐藏起来,于是我们就引入闭包函数。

闭包函数:一个函数的参数和返回值都是函数

  注:闭包本质上是一个函数

闭包函数的传入参数和返回值也都是函数

闭包函数的返回值函数是对传入函数增强后的结果

import time
def print_odds():for i in range(100):if i%2 ==1: print(i)
def count_time_wrapper(func):
#闭包,用于增强函数func,给函数func增加统计时间的功能def improved_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))return improved_funcif __name__ == "__main__":#调用count_time_wrapper增强函数  print_odds = count_time_wrapper(print_odds)print_odds()print(print_odds())

这是我们手动写了一段增强函数的代码来增强函数功能

print_odds = count_time_wrapper(print_odds)

然而我们需要一种机制,让python解释器自动增强,这时候python装饰器就来了

import time
def count_time_wrapper(func):def improved_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))return improved_func@count_time_wrapper
def print_odds():for i in range(100):if i % 2 == 1:print(i)if __name__ == "__main__":print_odds()

所有python装饰器本质上就是函数闭包,并且装饰器在第一次调用被装饰函数时进行增强。

上面的装饰器你会发现,里面并没有返回值和没有输入参数的,如果我的函数又返回值和输入参数,还能加强吗?

这里需要注意

对于有返回值的函数,调用闭包增强后,不能成功返回,但是增强了函数的辅助功能

import time
def count_time_wrapper(func):def improved_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))return improved_func@count_time_wrapper
count=0
def count_odds():   #统计计数的个数for i in range(100):if i % 2 == 1:count+=1return count   #这里增加了函数的返回值if __name__ == "__main__":print_odds()

对于含有参数的函数,调用闭包增强后,不能成功接收参数

import time
def count_time_wrapper(func):def improved_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))return improved_func@count_time_wrapper
count=0
def count_odds(lim=1000):   #统计计数的个数  这里还增加了参数for i in range(100):if i % 2 == 1:count+=1return count   #这里增加了函数的返回值if __name__ == "__main__":print_odds(lim=1000)

但是我们如何让这个闭包接收返回值和参数呢,参考如下代码

import time
def print_odds(lim=10000):cnt=0for i in range(100):if i%2 ==1:cnt+=1return cntdef count_time_wrapper(func):def improved_func(*args, **kwargs):   #增强函数应该吧接收到的所有参数传给原函数start_time = time.perf_counter()res=func(*args, **kwargs)         #传入参数并记录返回值end_time = time.perf_counter()print("it takes {} s to find all the odds".format(end_time - start_time))return res                        #返回未增强函数的返回值return improved_funcif __name__ == "__main__":print_odds = count_time_wrapper(print_odds)print_odds(lim=10000)

这样我们便实现了完美的闭包,后面还有多个装饰器的问题,但我就到此为止吧。

总结

  在学习完python的基础语法之后,就可以学习网络编程和爬虫了,这又是一个漫长的道路,在编程这条路上,我需要学习的东西还很多很多,并且需要不停学习,充实自己,现在python作为世界第一编程语言,的确有一些地方相对于c和java来说使用非常方便,这是也是我第一次第一次写博客,希望大家可以支持,同时身为智能科学与技术的大一新生,我也希望在编程这条路上我可以一直走下去,不断努力学习

关于Python中的基础问题与重点语法分析相关推荐

  1. [转载] Python中Numpy基础

    参考链接: Python中的numpy.less numpy的功能: 提供数组的矢量化操作,所谓矢量化就是不用循环就能将运算符应用到数组中的每个元素中.提供数学函数应用到每个数组中元素提供线性代数,随 ...

  2. python中最基础的文件操作,你都懂吗?

    今天讲一下python中的文件操作,虽然在开发中我们很少操作文件,大部分的需求基本上是在数据库中完成,因为数据库的数据更安全,操作效率高,操作文件就面临着我们需要自己管理文件,但是我们平常测试或者做一 ...

  3. python中0o10_Python基础10—I/O编程

    一.输入输出 ①输入:input() ②输出:print() 1 name=input('请输入名字')2 print(name) 二.文件操作 ①打开文件:文件对象=open(文件名,访问模式,bu ...

  4. python中day_python-day01 基础入门

    一.python介绍 Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言.Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有 ...

  5. python中uniform_Python基础之uniform()的详解

    描述 uniform() 方法将随机生成下一个实数,它在[x,y]范围内. 语法 以下是 uniform() 方法的语法:import random random.uniform(x, y) 注意:u ...

  6. 三、python中最基础的文件处理汇总

    文章目录 前言 一.分配train和val的训练数据 二.将一个文件夹的文件按比例复制给多个文件夹 三.多个txt文件的标签内容合并在一个txt文件 四.图片压缩(有损压缩和无损压缩) 五.多个txt ...

  7. Python 中的基础语句

    一. if-else 条件判断 条件判断的思路如下图 1 所示:当判断条件为 true 即符合条件时,进行规定的逻辑处理,如果判断条件为 false 即不符合条件时,进行另外的一个逻辑处理.    图 ...

  8. Python中正则表达式用法 重点格式以这个为准_首看_各种问题

    20210811 https://www.jb51.net/article/101258.htm 一.惰性模式的概念: 此模式和贪婪模式恰好相反,它尽可能少的匹配字符以满足正则表达式即可,例如: va ...

  9. python向量计算库教程_python中numpy基础学习及进行数组和矢量计算

    前言 在python 中有时候我们用数组操作数据可以极大的提升数据的处理效率,类似于R的向量化操作,是的数据的操作趋于简单化,在python 中是使用numpy模块可以进行数组和矢量计算. 下面来看下 ...

最新文章

  1. python 列表(list)操作及函数
  2. linux 设置ftp自启,CentOS vsftpd设置安装自启动配置
  3. SQL Server 2012笔记分享-29:日志文件的工作方式
  4. Java实体对象为什么一定要实现Serializable接口呢?
  5. 本期课程已满,欢迎关注后续期次 | 临床基因组学数据分析实战助力解析Case,快速发表文章...
  6. 动态规划——基本思想
  7. Maven 仓库、镜像
  8. unrecognized selector sent to instance问题的解决
  9. 问题六十四:怎么用C++实现二叉查找树(binary search tree)及其相关操作
  10. Java系统架构的演化之路
  11. laravel 5 : Class 'input' not found
  12. 在Vista系统中,Flash渲染功能无法使用,咋办?
  13. Struts2框架的概念及使用方法
  14. python 英语词典下载_Python 字典(Dictionary)
  15. 它们把色情版 “微信” 的底裤都给挖出来了,网友: 草率了。。。
  16. 【历史上的今天】6 月 26 日:EDSAC 计算机之父诞生;B 站成立;Skype 创始人出生
  17. SpringMVC之CRUD和文件上传下载
  18. ReactEurope Conf 参会感想
  19. Allegro如何快速删除孤立铜皮操作指导
  20. 各大电信运营商最新号段

热门文章

  1. SkyEye硬件模拟平台
  2. 四年级下册计算机技术做福字,四年级写福字作文
  3. Linux 大数据(hadoop)
  4. peewee和peewee_async常用汇总(持续更新)
  5. Pyinstaller Pmw
  6. 微博【黄金分析师吕超】--1.19黄金分析
  7. 支付宝app登录授权的infoStr授权登录流程
  8. iOS-利用粒子发射器(CAEmitterLayer) 制作发射动画
  9. 别 了,余 额 宝!
  10. 什么是php 抽象类