3天带你快速入门Python——还不快上车(冲鸭)

叮咚!问大家一个问题,学语言最重要的是什么?

是思想啊!是行动啊!是敲代码啊!是解决问题啊!

我们都知道,入门一门语言是很简单的,但是想要精通却没那么容易;我们也知道,一门语言的内容是又多又杂的,但是在实际开发中不是都那么常用;我们更知道,不同语言语法不同环境不同,但是语言本身的学习却是相通的。

所以我们在刚开始学习一门语言时,容易进入一个误区,那就是遇到比较偏僻的知识点时,容易钻牛角尖,觉得应该都学会才上手项目,其实不然。

我自己先后学习了C语言、C++、Java、Python,发现虽然是四种不同的语言,但是有相通的地方,自己也有一些感悟。

学习一门语言,如果很长时间不用,就会忘记,这是再正常不过的一件事情了,最重要的是怎么能够在短时间内捡起来。

而每一门语言包含的内容又非常零碎,所以学习一门语言的方法和思维框架就很重要。

这里我就小小分享一下我学习的方法~

Python学习方法

拿到一门语言,我比较倾向于,先学习基础的语法知识,然后再跟着做一两个综合性项目,将知识点更加融会贯通。

基础的语法知识,刚开始学习时,会觉得又多又杂,但是后来在学习c和python时,我重点对比了自己这两门语言的学习过程,发现可以运用逻辑,建立起学习框架。

因为一门语言逻辑框架的建立,不仅仅是学习该门语言,更重要的是可以将该逻辑框架,拓展到其他语言上,这样学习一门新的语言就会上手比较快!

基础语言知识,我是会先学习这门语言一个简单的程序格式及代码规范,然后去运行该示例程序,分析程序执行原理和执行过程,再开始正式学习语法知识。

语法知识相当于就是表达式、函数、流程控制、类和对象、文件、异常,然后再根据这些名词进行展开学习。

语法知识我是会先从一个表达式开始,比如c=a+b,这里就涉及到,运算数和运算符,于是就展开到,变量及运算符,变量又涉及到变量名(包含命名规则)、变量值、数据类型(基本、高级)、内存地址、局部变量与全局变量、可变类型和不可变类型、作用域和生存期等,运算符就涉及到运算符类型以及用法还有优先级等问题。

其次就是函数学习,分为函数名(命名规则、匿名函数)、返回值(有、无)、参数(多值参数、缺省参数)、函数体等。

变量和函数学完后,就到了整个程序的流程控制,是三大件,顺序结构、选择结构和循环结构。

对于面向对象的语言,还会学习到类和对象,类又有三大特性,封装、继承(单继承、多继承)、多态。

特性学完后,再学习与文件相关的操作。

整个学完后,还有模块、包、异常的概念。

通用的学完后,再就学习该语言所特有的知识点。

下面来具体进行到Python语言学习吧!

因为python知识点比较多,所以我们重点掌握其重点,其他的作为了解,然后写代码过程中遇到了再去查阅即可奥,不需要总想着知识点太多了记不住怎么办!!

因为某些原因,本文讲的是大概的学习思路,以及我学习过程中觉得比较重要的点的记录,没有写的特别特别全面奥!

解释型语言 or 编译型语言

首先来看看编译型语言和解释型语言的概念是什么。

我们都知道,计算机是不能直接识别高级语言的,计算机能够直接识别的是机器语言,所以我们需要将高级语言翻译成机器语言。

翻译的过程有两种,一种是编译,编译就是将程序源代码编译成可执行文件,对应的语言就叫做编译型语言,典型的就是c/c++,另一种是解释,解释就是将源代码读取一行翻译一行、翻译一行执行一行,对应的语言就叫做解释型语言,典型的就是java和python。

因为我们都知道,java运行是有一个JVM的,python对应的是PVM。

那么既然出现编译型语言和解释型语言,不免就会产生两者的对比了。

编译型语言,因为一次性可以产生可执行文件,所以执行速度相对于解释型语言会比较快;而解释型语言,因为读取一行翻译一行、翻译一行执行一行,所以可以跨平台,而编译型语言是不能跨平台的。

python是解释型语言,并且在Python中,万物皆对象!

人生苦短,我用Python!

一个简单程序格式及代码规范

一个比较常见的python完整程序格式是这样的:

#导入模块
#全局变量
#类
#函数
def main():
	pass
if __name__=="__main__"
	main()

需要注意的点有如下:

第一,python中是不需要一行语句后加上分号的,而且变量是不需要显示说明类型的,python解释器会动态识别变量类型,这点和其他语言不同。

第二,缩进对于python来说,是非常重要的,一般是四个空格或者Tab键,在使用时,选择一种即可,不要交叉使用,否则缩进不一致,会导致运行错误。

第三,对于一门语言,注释少不了,python中单行注释是#,快捷键是ctrl+/,多行注释是三对引号 ‘’‘注释内容’’’ 或者 “”“注释内容”"",注释是为了帮助我们更好的理解代码。

第四,在Python中,是非常注意代码的格式规范的,比如运算符前后都有一个空格,如果我们不习惯,可以写完代码后,选中需要格式化的代码,然后使用code——Reformat code格式化,让代码看起来简洁美观。

第五,输入输出也是学习一门语言的基础,在python中输入是input,其为阻断输入,需要给出一个信号告诉其输入结束,这个信号是换行!在python中输出是print,其默认含有换行,如果不想换行,可以使用print(“hello python!”,end="")即可!

第六,python的关键字后面,都可以不用加上括号(),但是方法或者函数是需要()的。

第七,python中比如if语句,其一行后使用的是冒号:,然后因为python中没有大括号(其实用于字典表示),所以采用缩进来表示if对应执行的代码。

第八,如果暂时不确定方法体写什么,可以使用pass占位符占位,这样就算运行也不会报错奥!

程序执行原理和程序执行顺序

说到程序执行原理,不得不说三大硬件,学过操作系统的应该都知道,CPU、内存和硬盘。

CPU,是中央处理器,负责数据的处理和运算。

内存,是负责临时存储数据,设备断电,数据就会消失。

硬盘,是永久存储数据,即使设备断电,数据也不会消失。

那么相应的内存和硬盘也有一些对比:

内存存储容量 < 硬盘存储容量
内存执行速度 > 硬盘执行速度

那我们知道,程序在执行前,是存储在硬盘中的,其执行速度较慢,而CPU是高速设备,如果直接cpu从硬盘中读取数据,就会速度不匹配,所以,在执行程序时,首先要做的事情,就是将数据从硬盘中装入到内存中,那么python解释器也是在内存中的。

分析程序执行顺序,这是十分重要的一个步骤,尤其是对于我们在调试代码时,或者,分析代码运行结果时。

DeBug中,先设置断点,再step over,当执行到函数时,可以使用step into进入函数体,再观察函数执行过程中相应参数的变化!

变量

变量名:用来标记变量。

变量名的命名规则如下:

  • 变量名可以包括字母、数字、下划线,但是数字不能做为开头。
  • 系统关键字和保留字不能做变量名使用。
  • 除了下划线之外,其它符号不能做为变量名使用。
  • Python的变量名是严格区分大小写的。

常用的变量名命名方法有两种:(大)驼峰法和下划线间隔法。

python中想要一次性修改所有类型变量,就选中该变量名,选择Refactor,点击rename,输入想更改为的名字,再点击refactor即可。

变量值:变量中存储的内容。

可以使用print(变量名)查看。

变量名和变量值存在如下关系,内存地址中存有变量值,变量名指向内存地址,可以称之为引用。赋值操作即是如此,比如a=10,变量值为10,系统为其分配内存空间,比如0x8132,然后a中存的就是该内存地址中的内容。
在这里插入图片描述

数据类型:变量所属的类型。

可以使用type(变量名)查看。

常见的数据类型如下:

简单类型:

  • 整型 int
  • 浮点型 float
  • 布尔型 bool

高级类型:

可以定义一个变量,然后使用dir(变量名)来查看其所有内置方法!!!
在这里插入图片描述

  • 列表 list(重点)

    1、其相当于其他语言中的数组,使用[]表示,下标从0开始。
    2、作用在于可以使用一个变量表示多个数值。
    3、常应用的场景是一个列表中存储相同类型的数据,然后对其进行迭代遍历操作。
    4、列表增删改查相关的函数,可以先定义一个列表变量,然后 列表名. 即可出现提示,如果选中函数后,也会出现函数相关的用法提示,以下列举几个较为常见的函数。


    • 列表名.append(需要增加的数据),其是将参数作为一个独立的插入到列表。
      列表名.insert(插入位置,需要增加的数据),其是将参数作为一个独立的插入到列表中对应的下标位置。
      列表名.extend(另一个列表),其是将另外一个列表的完整内容追加到当前列表末尾。
      在这里插入图片描述


    • 列表名.remove(要删除的数值),其参数为要删除的数值。
      列表名.clear(),其第一个参数为self,可不传递,其是清空列表。
      列表名.pop(要删除的数值下标),其参数为要删除的数值下标。
      在这里插入图片描述

    • :列表名[下标]=要修改成为的值。
      在这里插入图片描述

    • :列表名[下标]
      在这里插入图片描述

    • 长度
      len(列表名),表示整个列表的长度。
      列表名.count(某一数据),表示列表中某一数据的个数。
      在这里插入图片描述

    • 排序
      列表名.sort(reverse=True),对列表进行升序或者降序排序,参数可缺省,python中bool类型值的首字母大写!
      列表名.reverse(),列表翻转,即列表逆序。
      注意,列表是可变类型,所以每一次的操作,都是在上一次操作基础上进行的。
      在这里插入图片描述

    • 列表遍历
      for 变量名 in 列表名:
      相应的操作
      在这里插入图片描述

  • 字符串 str(重点)

    1、其使用"“或者’'表示,当需要输出双引号的时候,外层使用单引号即可。
    2、比如输出我是“大笨蛋”,则对应语句为print('我是"大笨蛋”’)。
    3、字符串*数字,表示的是重复。
    4、字符串拼接可以使用+。
    5、比如str = “我是” + “大笨蛋”。
    6、字符串切片:字符串名[开始位置:结束位置:步长],其是前闭后开区间。其下标从左到右依次为0,1,……,也可以从最右边到左边为-1,-2,……,可灵活使用。range函数和其参数类似,即是range(开始位置,结束位置,步长),其也是前闭后开区间。
    在这里插入图片描述
    切片可用于反转,即逆序。
    在这里插入图片描述

  • 元组 tuple

    1、其使用()表示。
    2、当函数中需要返回多个数据时,可以返回一个元组,即return (返回值1,返回值2,……),这种情况下()可以省略;在接收函数时,可以使用多个数据接收,其本质是也是一个元组,但是()也可以省略,即变量1,变量2,……=函数(参数列表),其变量个数要对应。
    3、也可以用于表示格式字符串输出,比如print(“我的名字是%s,年龄%d”%(name,age)),注意表示格式。
    4、元组不可变,一旦定义后,便不允许修改其中的内容。
    5、列表可以改变,而元组不允许改变,两者也可以互相转换类型,以满足业务需求。列表转换为元组的函数为tuple(),元组转换为列表的函数为list()。
    6、python交换两者,可以使用元组(a,b)=(b,a),其不需要第三个变量,其中()可以省略。
    在这里插入图片描述

  • 字典 dict

    1、其使用{}表示,并且无序,故输出时和定义的键值对顺序可能不一样。
    2、字典是键值对,其关心的不是数据存储数据的顺序,而是对应关系,其查找时,是用键来查找的值;而列表和元组是有序的,故可以用下标来查找对应的数据。
    3、键一般唯一,且要用""表示起来,而不是变量名,但是值可以任意。
    4、常用增删改查等同列表,此处不再一一赘述了。
    在这里插入图片描述

内存地址:系统为变量分配的内存地址。

可以使用id(变量名)查看。

可变类型和不可变类型:指的是内存地址中的内容是否可变!

其中列表和字典是可变类型,其余均是不可变类型。

局部变量和全局变量:全局变量可以认为是所有函数外定义的变量,局部变量一般是函数体内定义的变量。

想要在函数体内使用全局变量,则使用global关键字声明,想要在内层函数内使用外层函数定义的变量,则使用nonlocal关键字声明。

作用域与生存期,可以帮助我们更好的分析代码执行过程中,相应参数的变化。

运算符

运算符这一块,比较简单,这里讲一些重点。

第一,乘方,即幂运算,是**,比如2^3,即为2**3。
第二,取整除,是//,一般的/结果不是取整的。
第三,in和not in是字符串完整匹配,即字符串1是否完整的在或不在字符串2中。
第四,==是判断两个的内容是否相同,而is是判断两个是否为同一个对象,即内存空间是否相同。

在这里插入图片描述
在这里插入图片描述

函数

函数一定是定义加上调用,不调用函数,函数是无法执行的,注意这一点。

函数定义
在这里插入图片描述
函数返回值
使用return关键字

匿名函数
lamada
多值参数

*args接收一个元组,**kwargs接收一个字典。

def demo(num, *args, **kwargs):
    print(num)
    print(args)
    print(kwargs)


demo(1, 2, 3, 4, 5, name="小明", gender="男")


在这里插入图片描述
也可以这样来拆包。

def demo(num, *args, **kwargs):
    print(num)
    print(args)
    print(kwargs)


tuple1 = [2, 3, 4, 5]
dict1 = {
    "name": "小明",
    "gender": "男"
}
demo(1, *tuple1, **dict1)

在这里插入图片描述

缺省参数:在定义函数时,我们可以为某个参数指定一个默认值,有默认值的参数被称为缺省参数。在调用函数时如果没有传入缺省函数的值,则会使用默认值。缺省参数一定放在最后一个,格式为:参数=缺省值。

上面列表的sort就是一个缺省参数,看看怎么调用的。

def print_info(name, gender=True):
    # 要注意缺省参数放在参数列表的最后
    gender_text = "男生"
    if not gender:
        gender_text = "女生"
    print("%s是%s" % (name, gender_text))


print_info("小明")
print_info("小美", gender=False)

在这里插入图片描述

流程控制

  • 顺序结构
  • 选择结构
  • 循环结构

类和对象

讲到这里,就先要分清楚面向对象和面向过程的区别。

面向过程:将功能封装成函数,然后按照需求依次调用函数完成业务需求。重视步骤与过程,如果业务需求复杂,代码会变得很复杂,也无法进行很好的分工。

面向对象:不仅可以将功能封装成函数,还可以将编程过程中共有的一类事务封装成类型,同时还具有继承和多态的特性,这些特性有利用代码的复用和人员的分工,更加适合复杂的业务需求。

可以这样理解,面向对象是在面向过程的基础上,更大的封装。

面向过程更加关注步骤和其先后顺序,其功能封装成函数。而面向对象更加关注各司其职,专业的事情交给专业的人做,其分为类,类中封装有属性和方法。

封装 :是面向对象编程的一大特点,就是将事物共有的属性和方法封装 到一个类 中,外界通过类来创建对应的对象,对象的方法和属性细节 都被 封装 在 类的内部,只对外提供必需的功能,不需要的细节则隐藏起来。

类的定义

在这里插入图片描述

我们在定义类的时候,可以采取名词提炼法。
即如果是名词,则看其描述的是对象的属性还是类属性,即判断其是否不同的对象属性不一样,然后再归类。
即如果是动作,则看其整个执行的过程,在执行过程中,需要访问的是类属性还是实例属性,如果是类属性,那就是类方法,如果是实例属性,则为实例方法,如果都没有,那就是静态方法,如果都有,那就是实例方法,因为类只有一个,使用类名.属性即可访问。

类的私有属性和私有方法命名规则为__名字。

Python中万物皆对象,所以类也是一个特殊的对象,类对象。

类创建对象,叫做类的实例化。

类只有一份,类在实例化的时候,各对象有自己的内存空间,并保存自己的属性,但是类的各个实例对象共享一份方法。

class People(object):

    def __new__(cls, *args, **kwargs):
        return super().__new__(cls)

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return "姓名:%s,年龄:%d" % (self.name, self.age)


p = People("nick", 20)
print(p)

以此类为例,来讲一讲,类的重点内置方法,以及对其改写。

__new__

此为类的分配内存空间方法,其主要功能是分配空间,然后返回对象引用。

第一个参数必须为cls,其表示的是类本身。

在该函数中,访问该类的属性或者方法使用cls.属性名或者cls.方法名。

super()表示的是父类,在python中Object是所有类的基类。

在单例设计模式中,即让类创建的对象,在系统中只有唯一的实例,也就是说,创建的对象,其内存地址相同,比如歌曲播放。

这种情况下,重写该方法非常固定!!

# 定义类属性记录单例对象引用
instance = None

def __new__(cls, *args, **kwargs):

    # 1. 判断类属性是否已经被赋值
    if cls.instance is None:
        cls.instance = super().__new__(cls)

    # 2. 返回类属性的单例引用
    return cls.instance

__init__

此为类的初始化方法,其主要功能是对象初始化,然后定义实例属性。

第一个参数必须为self,其表示的是调用此方法的对象。

在该函数中,访问该对象的属性或者方法使用self.属性名或者self.方法名。

如果我们想在对象初始化的时候,给其设置属性,可以将其属性在此方法中初始化,而需要传进来的属性可以放在其参数里。

如果定义属性的时候,不知道设置什么初始值,可以在该方法中对该属性赋值为None,然后在外部对该属性赋值,其中None是python中的空对象。

只让初始化执行一次如下:

 # 记录是否执行过初始化动作
  init_flag = False
    
  def __init__(self):

        if not MusicPlayer.init_flag:
            print("初始化音乐播放器")

            MusicPlayer.init_flag = True
__str__

输出对象时,系统默认输出的是对象所属的类和内存地址,如果相要改变输出对象时的输出内容,在此方法中改变return的内容。

音乐播放器如下:

class MusicPlayer(object):
    # 记录第一个被创建对象的引用
    instance = None
    # 记录是否执行过初始化动作
    init_flag = False

    def __new__(cls, *args, **kwargs):

        # 1. 判断类属性是否是空对象
        if cls.instance is None:
            # 2. 调用父类的方法,为第一个对象分配空间
            cls.instance = super().__new__(cls)

        # 3. 返回类属性保存的对象引用
        return cls.instance

    def __init__(self):

        if not MusicPlayer.init_flag:
            print("初始化音乐播放器")

            MusicPlayer.init_flag = True


# 测试:
# 创建多个对象
player1 = MusicPlayer()
print(player1)
player2 = MusicPlayer()
print(player2)

在这里插入图片描述
继承,分为单继承和多继承,即子类可以继承父类的非私有属性和非私有方法。
在这里插入图片描述
这里我随便举一个例子,主要来说明其中的重要知识点。

class A:
    def funAB(self):
        print("我是A")


class B:
    def funAB(self):
        print("我是B")


class C(B, A):
    pass


c = C()
c.funAB()


在这里插入图片描述
第一,可以使用以下方法查看类的方法检索顺序。

print(类名.__mro__)

在这里插入图片描述
第二,在继承中,如果父类方法不够满足自己的需求,则可以在继承父类属性和方法的基础上自己再定义新的方法;如果父类的某个方法和自己的需求不太相同,可以改写父类的方法;如果子类的方法中包含父类的方法,即父类的方法是子类的一部分,则子类重写该方法,并且在需要的位置进行super().父类方法即可,super()表示父类对象。

第三,在多继承中,父类们的属性方法,尽量不要重名,如果有重名发现结果和自己预期不一样,可以分析程序执行顺序以及结合第一条内容。

综上所述,封装是定义类的准则,在外部只需要创建对象,然后调用相应的属性或者方法,而不需要关心类内部的细节;继承是设计类的技巧,相同的代码,不需要重复编写;多态是增加代码的灵活度,不同的对象调用相同的方法,产生不同的结果。

文件

说到文件,不得不讲讲ASCII编码和UNICODE编码。

ASCII编码,是最初美国人使用的,一个ASCII占一个字节,一共2^8=256个ASCII,完全够英文的。

但是中文数以万计,ASCII肯定不够,所以有一种新的UNICODE编码,UTF-8就是UNICODE的一种。

其一个是占1~6个字节,其中汉字占有3个字节。

对于文件的操作,一般都是打开文件、读写文件、关闭文件。

在这里插入图片描述
在这里插入图片描述
打开文件:默认只读

file = open("文件路径",打开方式)

关闭文件:

file.close()

读文件:

#小文件一次性读
text = file.read()
print(text)

#大文件按行读 缓解内存紧张
file = open(文件路径) 
while True:
  line = file.readline()
  if not line:
    break
  print(line,end="")
file.close()

写文件:

file.write("要写的内容")

另外还有一个文件指针,是标记文件当前位置!

异常

首先来看看异常是什么!异常即为程序运行时,如果出现错误,就会抛出异常,但是这个异常不是给用户的,而是抛给程序员,程序员处理后,返回给用户,程序员也可以主动抛出异常,异常的处理可以使程序具有更好的稳定性和健壮性。

完整的异常处理代码如下:

try:
    num = int(input("请输入一个整数:"))
    s = 8 / num
    print("结果为 %.1f" % s)
except ValueError:
    print("请输入正确的整数")
except ZeroDivisionError:
    print("除零错误")
except Exception as result:
    print("未知错误 %s" % result)
else:
    print("没有发生异常")
finally:
    print("无论有无异常,都会执行")

当然我们也可以主动抛出异常!

异常的存在有什么好处呢?我们应该怎么使用异常呢?

假设现在有三个函数,A调用B,B调用C,如果我们在A,B,C中都设置异常,那我们写这么多异常,岂不是要累死!

别慌,由于异常具有传递性,故我们只需要在主函数中写清楚异常就可以了!!

模块

每一个.py文件,都可以看作是一个模块。

我们可以这样理解,一个模块就是一个工具包,而一个函数就是一个工具。

我们在编写代码的时候可以导入模块,然后调用模块中的方法!

第一,导入整个模块。

import 模块名

第二,导入多个模块,起别名。

import 模块名1 as 别名1
import 模块名2 as 别名2

上述两个调用的时候,都是模块名.方法名。

第三,导入模块中的部分工具。

from 模块名 import 工具名

调用的时候,是直接工具名即可。

建议编写的时候,一个模块的导入写一行,因为这样方便检查错误。

如果导如一个模块的时候,就会运行此模块中的代码,所以控制台做了输出,这不是我们想看的的,那怎么办?

使用__name__内置属性!当你直接执行一段脚本的时候,这段脚本的 __name__变量等于 __main__,当这段脚本被导入其他程序的时候,__name__ 变量等于脚本本身的名字。

我们看看pycharm自带的main.py就有!

# This is a sample Python script.

# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.


def print_hi(name):
    # Use a breakpoint in the code line below to debug your script.
    print(f'Hi, {name}')  # Press Ctrl+F8 to toggle the breakpoint.


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    print_hi('PyCharm')

# See PyCharm help at https://www.jetbrains.com/help/pycharm/

模块搜索顺序:

使用__file__属性

安装第三方模块:

pip install 模块名

卸载第三方模块:

pip uninstall 模块名

我们知道包可以干什么?包治百病

来讲讲包!

当我们要对多个模块进行分类管理的时候,就需要使用包。就像我们用文件件对多个文件进行分类管理一样。我们把有相似功能的模块存放在一个包下面,比如图片文件放一个文件夹,文本文件放一个文件夹。

包是一种通过使用‘.模块名’来组织 python 模块名称空间的方式。包就是一个包含有__init__.py文件的文件夹,所以其实我们创建包的目的就是为了用文件夹将文件/模块组织起来。

我们需要配置该文件!

有时候我们的多个模块中可能需要 import 多个资源,每次都手动添加会比较繁琐,我们可以创建一个包 c,在__init__.py 中导入这些模块,然后在其它需要导入这些模块的文件中导入 c 这个包就可以了。

结束

至此,基础语法已经接近尾声,但这仅仅只是一个开始,继续敲代码吧,加油!!

码字不易,各位客官,这不点个赞再走?

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值