python基础_python基础教程 - CSDN
精华内容
参与话题
  • Python基础知识总结

    万次阅读 多人点赞 2018-10-31 12:49:38
    Python基础知识总结 基础中的基础 列表、元组(tuple)、字典、字符串 变量和引用 函数 面向对象 基础中的基础 解释型语言和编译型语言差距; Python概述 解释器执行原理 which python3可以...

    Python基础知识总结

    • 基础中的基础
    • 列表、元组(tuple)、字典、字符串
    • 变量和引用
    • 函数
    • 面向对象(封装、继承、多态)
    • 异常
    • 模块、包
    • 文件

    基础中的基础

    • 解释型语言和编译型语言差距;
      在这里插入图片描述
    • Python概述
      在这里插入图片描述
    • 解释器执行原理
      在这里插入图片描述
    • which python3可以查看python3的位置(linux下);
    • 交互式环境中使用exit()或者ctrl+D退出;
    • 9 // 2表示取结果的整数,乘方使用**;
    • 乘法可以用在 字符串中 也就是说 "_ " * 5 会输出5个 “_”;
    • 数据类型分为 数字型和非数字型: (1)数字型 : 整形、浮点型、布尔型、复数型。(2)非数字型: 字符串、列表、元组、字典。type(变量名)查看变量类型;
    • python3中没有long,只有int;
    • 变量的输入: input()函数。注意: input()函数输入的数据类型都是字符串类型;
    • 在python中,如果变量名需要两个或多个单词组成时,可以按照下面的方式: ①每个单词都是小写;②单词和单词之间使用_下划线连接;③使用驼峰规则;
    • print函数如果不想输出换行,在后面加上一个end=""(例如print(“a”,end=""));单纯的只想输出一个换行可以使用print()或者print("");
    • \t(制表符(对齐))和\n转义字符;
    • 关于函数的注释,写在函数的下面,加上三个"""。以及文档注释,例如:
    def sum_2_sum(a, b):
        """计算a和b的和
        :param a:第一个参数
        :param b:第二个参数
        :return:
        """
        return a + b
    
    • 因为函数体相对比较独立,函数定义的上方,应该和其他代码(包括注释)保留两个空行;
    • import导入的文件可以python解释器将模块解释成一个pyc二进制文件(类似Java的.class?);
    • python中关键字后面不需要加括号(如del 关键字);
    • 方法和函数的异同: ①方法和函数类似,同样是封装了独立的功能;②方法需要通过对象来调用,表示针对这个对象要做的操作③函数需要记住,但是方法是对象的"函数",方法不需要记住(IDE提示或者IPython中TAB补全);
    • 变量赋值的几种特殊的方式:
    a = b = c = 1  # 三个都是1
    a, b, c = 1, 2, "hello"  # a = 1, b = 2, c = "hello"
    
    a, b = 0, 1
    a, b = b, a+b  # 右边表达式的执行顺序是从左往右的。
    """
    上面的代码类似: 
    n = b
    m = a+b
    a = n
    b = m
    """
    print(a)  # 1
    print(b)  # 1
    
    • 逻辑运算符:and、or、not,成员运算符in、not in,身份运算符is、is not

    列表、元组(tuple)、字典、集合、字符串

    • 列表可以嵌套;
    x = [['a', 'b', 'c'], [1, 2, 3]]
    print(x[0])  # ['a', 'b', 'c']
    print(x[0][1])  # 'b'
    
    • 元组不同于列表的是: 元组不能修改,用()表示;(不能增删改)
    • 元组一般保存不同类型的数据;
    • 注意: 只有一个元素的元组: single_tuple = (5,) ,也就是说元组中只包含一个元素时,需要在元素后面添加逗号;不能这样写 single_tuple = (5),这样是一个整形的变量;另外,创建元组也可以不加上括号;
    tup = "a", "b", "c", "d"
    print(tup)
    print(type(tup))
    
    tup2 = ("a",)  # 一个元素的元组 (后面必须加上一个括号)
    print(tup2)
    print(type(tup2))
    
    

    输出:

    ('a', 'b', 'c', 'd')
    <class 'tuple'>
    ('a',)
    <class 'tuple'>
    
    • 元组的用途: ① 作为函数的参数和返回值;②格式化字符串(格式字符串本身就是一个元组);(3)让列表不可以被修改,保护数据安全;
    • 格式化字符串和元组的关系,看下面的三个print输出是一样的:
    # 元组和格式化字符串的关系
    info_tuple = ("小明", 21, 1.85)
    print("%s 年龄是 %d 身高是 %.2f" % ("小明", 21, 1.85))
    print("%s 年龄是 %d 身高是 %.2f" % info_tuple)
    
    info_str = "%s 年龄是 %d 身高是 %.2f" % info_tuple
    print(info_str)
    
    • 元组和列表可以相互转换 : ①使用list(元组)将元组转换成列表;②使用tuple将列表转换成元组;
    • 字典: ① 键必须是唯一的 ②值可以取任意类型,但是键只能使用字符串、数字或者元组(键只能是不可变类型)。
    • **遍历字典的时候for k in dict 中的k是键,而不是值。(普通的for),不过也可以通过items()方法遍历键值对: **
    dict_student = {'name': 'xiaoming', 'age': '18', 'qq': "1234"}
    
    # 遍历方式一
    for k in dict_student:  # k 是key
        print(k, end=" ")
        print(dict_student[k])
    
    print("*" * 20)
    # 遍历方式二
    for k, v in dict_student.items():
        print(k, v)
    
    • 字符串中的转义字符:\n表示换行,而\r表示回车,字符串中的函数isspace()判断的时候\t\n\r都是表示的空白字符;
    • isdecimla()、isdigit()、isnumeric()都不能判断字符串中的小数,(可以判断字符串中的整数);
    • 集合set的使用: 可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。 集合还有一些方法add()、update()、pop()等;
    student = {'Tom', 'Jim', 'Mary', 'Tom', 'Jack', 'Rose'}
    print(student)  # 输出集合,重复的元素被自动去掉
    
    if 'Rose' in student:
        print('Rose 在集合中')
    else:
        print('Rose 不在集合中')
    
    # set可以进行集合运算
    a = set('abracadabra')
    b = set('alacazam')
    
    print(a - b)  # a和b的差集
    print(a | b)  # a和b的并集
    print(a & b)  # a和b的交集
    print(a ^ b)  # a和b中不同时存在的元素
    

    输出:

    {'Jim', 'Mary', 'Jack', 'Rose', 'Tom'}
    Rose 在集合中
    {'b', 'd', 'r'}
    {'b', 'l', 'c', 'd', 'z', 'm', 'a', 'r'}
    {'c', 'a'}
    {'b', 'm', 'l', 'r', 'd', 'z'}
    
    • 相关公共方法: len、del、max、min(只会比较字典的key);
    • in、not in的使用(类似数据库…);
    • pass关键字的使用: 比如if … 下面没有写语句,python会提示报错,但是你可以写一个pass就不会报错了;也就是说如果在开发程序时,不希望立即编写分支内部的代码,可以使用pass作为一个占位符;可以保证程序代码结构正确;
    • TODO关键字的使用,在编写程序框架的时候,可以用TODO标示某个地方还没有做某事;
    • 迭代器的使用
    import sys  # 引入 sys 模块
    
    lst = [1, 2, 3, 4]
    it = iter(lst)  # 创建迭代器对象
    
    # 使用for 遍历迭代器
    for x in it:
        print(x, end=" ")
    print()
    
    it = iter(lst)  # 之前那个已经到了最后了,再次获取
    # 使用next + while遍历
    while True:
        try:
            print(next(it), end=" ")
        except StopIteration:  # 防止无限循环
            sys.exit()  # 退出程序
    print()
    

    输出:

    1 2 3 4 
    1 2 3 4 
    
    • 字符串中切片的使用: ①类似截取,但是可以指定步长;②python中支持倒序索引,最后一个是-1,倒数第二个是-2…;
      在这里插入图片描述
    # 切片的使用
    num_str = "12345678"
    
    print(num_str[2:6])  # [2,5]
    print(num_str[2:])  # 从2位置到结束
    print(num_str[0:6])  # 输出[0,5]的
    print(num_str[:6])  # 一开始到5的
    print(num_str[:])  # 全部输出
    print(num_str[::2])  # 指定步长  第三个参数指定步长
    print(num_str[1::2])  # 从第一个开始 步长为2
    
    print("*" * 20)
    print(num_str[-1])  # 输出最后一个位置的
    print(num_str[2:-1])  # 从第二个开始到倒数第二个
    
    print("*" * 20)
    # 一个面试题 逆序输出
    print(num_str[-1::-1])  # 步长为-1代表向左切片,从最后一个开始切
    print(num_str[::-1])
    

    输出:

    3456
    345678
    123456
    123456
    12345678
    1357
    2468
    ********************
    8
    34567
    ********************
    87654321
    87654321
    

    变量和引用

    • 变量和数据都是保存在内存中的;
    • 在python中函数的参数传递以及返回值都是引用传递的;
    • 变量和数据是分开存储的;
    • 变量中记录数据的地址,就叫做引用;
    • 使用id()函数可以查看变量中保存的数据所在的内存地址;
    • 注意: 如果变量已经被定义,当给一个变量复制的时候,本质上是修改了数据的引用。① 变量不再对之前的数据引用;②变量改为对新复制的数据引用;
    • 可变类型和不可变类型

    不可变类型: 内存中的数据不允许修改:

    ① 数字类型: intboolfloatcomplexlong
    ② 字符串 :str
    ③ 元组 :tuple

    可变类型: 内存中的数据可以被修改

    ① 列表 list
    ② 字典 dict

    • 可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a;
    • 不可变类型: 变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。

    函数参数传递时注意:

    • 不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
    • 可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响;
    • 局部变量和全局变量

    局部变量:函数内部定义的变量,只能在函数内部使用;
    全局变量: 函数外部定义的变量,所有函数内部都可以使用这个变量;(不推荐使用)

    注意: 在python中,不允许修改全局变量的值,如果修改,会在函数中定义一个局部变量;

    num = 10
    
    
    # python中,不允许修改全局变量
    
    def method1():
        num = 99  # 这里没有修改全局变量num,而是自己又定义了一个局部变量,执行完这个函数,局部变量就会回收
        print(num)
    
    
    def method2():
        print(num)  # 虽然在method1中修改了 num 但是却不会修改
    
    
    method1()
    method2()
    
    # 输出
    # 99
    # 10
    
    • 可以使用global关键字修改全局变量的值。
    • 全局变量的命名规则: 前面加上g_ 或者gl_

    函数

    • 函数如果返回的是一个元组就可以省略括号;
    • 如果返回的是一个元组,可以使用多个变量直接接收函数的返回结果;(注意变量的个数和返回的元组的个数相同)

    例如:

    def measure():
        """测量湿度和温度"""
        temp = 39
        wetness = 50
    
        # 下面返回的是一个元组,为什么写成没有括号的样子,因为如果返回的是一个元组就可以省略括号
        # return (temp, wetness)
        return temp, wetness
    
    
    res = measure()
    print(res)
    print(type(res))  # tuple
    
    
    # 很骚的,直接使用多个变量接收函数返回的元组
    gl_temp, gl_wetness = measure()
    print(gl_temp)
    print(gl_wetness)
    
    • 交换两个变量a、b的值的三种解法(第三种python专用)
    a = 6
    b = 100
    
    # 解法1
    c = a
    a = b
    b = c
    print(a)
    print(b)
    
    # 解法2
    
    a = a + b
    b = a - b
    a = a - b
    print(a)
    print(b)
    
    # 解法3 python专用
    # a, b = (b, a)
    a, b = b, a
    print(a)
    print(b)
    
    • 如果在函数中使用赋值语句,并不会影响调用函数时传递的实参变量;无论传递的参数可变还是不可变;
    • 只要针对参数使用赋值语句,会在函数内部修改局部变量的引用,不会影响到外部变量的引用;

    测试:

    def demo(num, num_list):
        print("函数内部的代码")
    
        num = 100
        num_list = [1, 2, 3]
    
        print(num)
        print(num_list)
        print("函数执行完成")
    
    
    gl_num = 99
    gl_list = [4, 5, 6]
    demo(gl_num, gl_list)
    print(gl_num)  # 99
    print(gl_list)  # [4, 5, 6]
    

    输出:

    函数内部的代码
    100
    [1, 2, 3]
    函数执行完成
    99
    [4, 5, 6]
    

    一张图解释:
    在这里插入图片描述

    • 如果传递的参数是可变类型,在函数内部,使用方法修改了数据的内容,同样会影响到外部的数据。
    def demo(num_list):
        print("函数内部的代码")
        num_list.append(666)
        print(num_list)
        print("函数代码执行结束")
    
    
    gl_list = [1, 2, 3]
    demo(gl_list)
    print(gl_list)
    

    输出:

    函数内部的代码
    [1, 2, 3, 666]
    函数代码执行结束
    [1, 2, 3, 666]
    

    示意图:
    在这里插入图片描述

    上面写了,这里再重复一遍可变类型和不可变类型和参数传递的关系:

    • 不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
    • 可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响;
    • 列表变量调用 += 的时候相当于是调用extend,这个是一个特列;
    def demo(num, num_list):
        print("函数开始")
    
        # 赋值语句 不会改变外部
        num += num
    
        # 但是列表是一个特例,+=列表相当于 extend 所以会改变外部
        num_list += num_list
        # num_list = num_list + num_list  # 这样就不会改变实参
    
        print(num)
        print(num_list)
    
        print("函数结束")
    
    gl_num = 9
    gl_list = [1, 2, 3]
    
    demo(gl_num, gl_list)
    
    print(gl_num)
    print(gl_list)
    

    输出:

    函数开始
    18
    [1, 2, 3, 1, 2, 3]
    函数结束
    9
    [1, 2, 3, 1, 2, 3]
    
    • 缺省参数: ①定义函数时,可以给某个参数指定一个默认值,指定了默认值的参数叫做缺省参数;②一般使用最常见的值作为缺省参数;③缺省参数的定义位置:必须保证带有默认值的缺省参数定义在参数列表的末尾;
    def print_info(name, gender=True):
        gender_text = "男生"
        if not gender:
            gender_text = "女生"
        print("%s 是 %s" % (name, gender_text))
    
    print_info("小明")  # 缺省参数 使用最常见的值,作为缺省参数
    print_info("小美", False)
    
    

    还要注意,如果后面有多个参数,且只给具体的某一个指定默认值,就要具体的指定参数的名字:

    def print_info(name, title="", gender=True):
        gender_text = "男生"
        if not gender:
            gender_text = "女生"
        print("%s 是 %s" % (name, gender_text))
    
    print_info("小明") 
    print_info("小美", False)  # 这个是错误的
    print_info("小美", gender=False)  # 这里必须指定为gender
    
    

    输出:
    在这里插入图片描述
    这个原理类似降序排序:

    gl_list = [6, 3, 9]
    gl_list.sort(reverse=True)
    print(gl_list)
    
    • 多值参数
      在这里插入图片描述
    def demo(num, *args, **kwargs):  # 多值参数 *接收元组 **接收字典
        print(num)
        print(args)
        print(kwargs)
    
    
    demo(1, 2, 3, 4, 5, name="小明", age=18)
    

    输出:

    1
    (2, 3, 4, 5)
    {'name': '小明', 'age': 18}
    

    使用多值参数的好处,例如下面的例子计算求和,如果不使用* args 也就是不使用多值的元组的时候,我们传递参数的时候就需要传递一个元组,但是这样的话就直接传递一串数字就好了。

    def sum_number(*args):
        res = 0
        for n in args:
            res += n
        return res
    
    
    print(sum_number(1, 2, 3, 4, 5))
    # print(sum_number((1, 2, 3, 4, 5)))  # 如果不加上*的话就要加上这个表示元组的括号
    
    • 多值参数元组和字典的拆包
      在这里插入图片描述

    首先看下面代码的输出,这个代码是出乎意料的:

    def demo(*args, **kwargs):
        print(args)
        print(kwargs)
    
    
    gl_tuple = (1, 2, 3)
    gl_dict = {"name": "小明", "age": 18}
    
    demo(gl_tuple, gl_dict)
    

    输出:

    ((1, 2, 3), {'name': '小明', 'age': 18})
    {}
    

    加上拆包:

    def demo(*args, **kwargs):
        print(args)
        print(kwargs)
    
    
    gl_tuple = (1, 2, 3)
    gl_dict = {"name": "小明", "age": 18}
    
    demo(*gl_tuple, **gl_dict)  # 注意这里加上了拆包 类似与之前的传递参数
    

    输出:

    (1, 2, 3)
    {'name': '小明', 'age': 18}
    

    面向对象(封装、继承、多态)

    • 类中: ①特征被称为属性;②行为被称为方法;③三要素:类名、属性、方法;
    • dir函数可以查看对象的所有方法;
    • dir显示的方法中,__方法名__格式的方法是Python提供的内置方法/属性

    在这里插入图片描述

    • 类中的方法第一个参数必须是self(类似Java中的this?);

    创建第一个类:

    class Cat:
        def eat(self):
            print("小猫爱吃鱼!")
        def drink(self):
            print("小猫爱喝水!")
    
    
    tom = Cat()  # 和Java不同,不需要使用 new
    tom.eat()
    tom.drink()
    
    print(tom)  # 输出对象变量
    print("%x" % id(tom))  # 输出16进制的地址
    print("%d" % id(tom))  # 输出10进制的地址
    

    输出:
    在这里插入图片描述

    • 引用的强调
      在这里插入图片描述
    • Python如果不想修改类,可以直接给对象增加属性(不同于其他语言!)(这种方式不推荐)
    • self关键字(Java中的this关键字): 哪一个对象调用的这个方法,self就是哪个对象的引用,可以通过self.访问对象的属性和方法;
    • 初始化方法__init__

    当使用类名()创建对象时,会自动执行以下操作:

    ①. 为对象在内存中分配空间 – 创建对象;
    ②. 为对象的属性 设置初始值 – 初始化方法(init);

    这个初始化方法就是__init__方法,__init__是对象的内置方法
    __init__方法是专门用来定义一个类具有哪些属性的方法!

    • 在初始化方法__init__内部定义属性:
    • init方法内部使用self.属性名 = 属性的初始值就可以定义属性;
    • 定义属性之后,再使用该类创建的对象,都拥有该属性;

    使用:

    class Cat:
        def __init__(self):
            print("这是一个初始化方法")
            self.name = "Tom"
    
        def eat(self):
            print("%s 爱吃鱼" % self.name)
    
    
    tom = Cat()
    print(tom.name)
    tom.eat()
    

    输出:

    这是一个初始化方法
    Tom
    Tom 爱吃鱼
    
    • 初始化方法__init__中带参数,构造对象;
    class Cat:
        def __init__(self, new_name):
            print("这是一个初始化方法")
            self.name = new_name
    
        def eat(self):
            print("%s 爱吃鱼" % self.name)
    
    
    tom = Cat("Tom")
    print(tom.name)
    tom.eat()
    
    lazy_cat = Cat("大懒猫")
    print(lazy_cat.name)
    lazy_cat.eat()
    
    
    • __del__方法的调用
      在这里插入图片描述
    class Cat:
        def __init__(self, new_name):
            print("初始化方法被调用")
    
        def __del__(self):
            print("del方法被调用")
    
    
    # tom是一个全局变量 等到程序全部执行完成之后才会销毁
    tom = Cat("Tom")
    
    # 可以手动调用 del tom 提前销毁 tom对象
    # del tom
    print("*" * 50)
    

    输出: (注意: 如果不注释 # del tom,__del__方法的调用就在输出横线的上方)

    初始化方法被调用
    **************************************************
    del方法被调用
    
    • __str__方法(类似Java中的toString())
    • 在python中,使用print输出对象变量,默认情况下输出这个变量 引用的对象由哪一个类创建的对象以及在内存中的地址(16进制表示)
    • 如果在开发中,希望使用print输出对象变量时,能够打印自定义内容,就可以利用__str__方法
    • 注意:__str__方法必须返回一个字符串;
    class Cat:
        def __init__(self, new_name):
            self.name = new_name
    
        def __str__(self):  # 返回的是一个字符串
            return "我是小猫【%s】" % self.name
    
    
    tom = Cat("Tom")
    print(tom)
    

    输出:

    我是小猫【Tom】
    
    • 面向对象案例一 : 房子和家具
    class HouseItem:
        def __init__(self, name, area):
            self.name = name
            self.area = area
    
        def __str__(self):
            return "家具名称: %s, 家具面积: %s " % (self.name, self.area)
    
    
    class House:
        def __init__(self, house_type, area):  # 房子类型, 总面积
            self.house_type = house_type
            self.area = area
            self.free_area = area  # 一开始剩余面积等于总面积
            self.item_list = []  # 家具列表一开始是空的
            pass
    
        def __str__(self):
            # python 能够自动的将一对括号内内部的代码 连接在一起
            return ("户型: %s\n总面积: %.2f【剩余: %.2f】\n家具: %s"  # 如果没有使用括号,这里就要有一个 \ 换行标符
                    % (self.house_type, self.area,
                       self.free_area, self.item_list))  # 注意这里使用了一个括号
    
        def add_item(self, item):  # 在列表中添加家具
            if self.free_area < item.area:
                print("房子已满,不能再放家具了!")
                return
            self.item_list.append(item.name)
            self.free_area -= item.area
    
    # 创建家具
    bed = HouseItem("席梦思", 40)
    chest = HouseItem("衣柜", 2)
    table = HouseItem("餐桌", 20)
    
    # 创建房子
    my_home = House("两室一厅", 60)
    print(my_home)
    
    # 添加家具
    my_home.add_item(bed)
    print(my_home)
    my_home.add_item(chest)
    print(my_home)
    my_home.add_item(table)
    print(my_home)
    

    输出:

    户型: 两室一厅
    总面积: 60.00【剩余: 60.00】
    家具: []
    户型: 两室一厅
    总面积: 60.00【剩余: 20.00】
    家具: ['席梦思']
    户型: 两室一厅
    总面积: 60.00【剩余: 18.00】
    家具: ['席梦思', '衣柜']
    房子已满,不能再放家具了!
    户型: 两室一厅
    总面积: 60.00【剩余: 18.00】
    家具: ['席梦思', '衣柜']
    
    • 面向对象案例二 : 枪和士兵
    class Gun:  # 枪类
        def __init__(self, model): 
            self.model = model
            self.bullet_mount = 0
    
        def add_bullet(self, count):
            self.bullet_mount += count
    
        def shoot(self):
            if self.bullet_mount <= 0:
                print("【%s】没有子弹了..." % self.model)
    
            self.bullet_mount -= 1
            print("%s 突突突...【剩余子弹: %d】" % (self.model, self.bullet_mount))
    
    
    class Soldier:
        def __init__(self, name):
            self.name = name
            # 这个使用None关键字 假定新兵没有枪
            self.gun = None  # Node类似Java中的null
    
        def fire(self):
            # 1.判断士兵是否有枪
            # if self.gun == None:  # 不推荐
            if self.gun is None:
                print("【%s】 还没有枪..." % self.name)
                return
            # 2. 高喊口号
            print("冲鸭...【%s】" % self.name)
            # 3. 让枪装填子弹
            self.gun.add_bullet(50)
            # 4.让枪发射子弹
            self.gun.shoot()
    
    
    # 创建枪的对象
    ak47 = Gun("AK47")
    ak47.add_bullet(50)
    ak47.shoot()
    
    # 创建士兵对象
    xusanduo = Soldier("许三多")
    xusanduo.fire()  # 没有枪,打不了
    xusanduo.gun = ak47  # 给士兵一把ak47的枪
    xusanduo.fire()
    
    
    
    • 身份运算符( == 类似Java中的equals,而 is(身份运算符) 却类似 java中的 ==);
      在这里插入图片描述
    a = [1, 2, 3]
    b = [1, 2, 3]
    
    print(a == b)  # True
    print(a is b)  # False
    
    
    • 私有属性和私有方法: 只需要在属性名或者方法名前面加上两个下划线(真的6…),私有属性只能在类的内部使用;
    • 但是Python中没有真正意义的私有,这个私有只是伪私有可以使用_类名__属性或者_类名__方法强制访问私有属性或方法;
    class Woman:
        def __init__(self, name):
            self.name = name
            self.__age = 18  # 加上两个_表示私有属性
    
        def secret(self):
            # 注意对象内部可以访问私有属性
            print("%s 的年龄是 %d" % (self.name, self.__age))
    
    
    xiaomei = Woman("小美")
    
    # print(xiaomei.__age)  # 报错,不能直接访问私有方法
    xiaomei.secret()  # 这个可以
    
    # 但是也可以通过 " _类名__属性/方法"  来强制访问私有属性或方法
    print(xiaomei._Woman__age)  # 强制访问
    
    

    输出:

    小美 的年龄是 18
    18
    
    • 关于继承中的重写,和Java中差不多,直接覆盖即可;
    class Animal:
    
        def eat(self):
            print("吃!")
    
        def drink(self):
            print("喝!")
    
        def run(self):
            print("跑!")
    
        def sleep(self):
            print("睡")
    
    
    class Dog(Animal):  # 继承直接加上括号,不需要extends 关键字
    
        def bark(self):
            print("汪汪汪!")
    
    
    class XiaoTianQuan(Dog):  # 继承可以传递,既继承了Animal也继承了Dog
    
        def fly(self):
            print("飞!")
    
        def bark(self):  # 重写方法
            print("嗷嗷嗷!")
    
    
    xiao_tian = XiaoTianQuan()
    xiao_tian.eat()
    xiao_tian.drink()
    xiao_tian.bark()
    xiao_tian.fly()
    
    • 扩展相关方法中使用super()关键字,和Java也差不多;
    class XiaoTianQuan(Dog):  # 继承可以传递,既继承了Animal也继承了Dog
    
        def fly(self):
            print("飞!")
    
        def bark(self):  # 重写方法
            super().bark()  # 先调用父类的方法  #注意这个super()关键字在python2.x中没有
            print("嗷嗷嗷!")
    
    • 注意子类不能访问父类的私有属性
    class A:
        def __init__(self):
            self.num1 = 3  
            self.__num2 = 33
    
        def __test(self):
            print("num1 = %d, num2 = %d" % (self.num1, self.__num2))
    
    
    class B(A):
        def demo(self):  # 测试能不能访问父类的私有方法
            # 访问父类的私有属性
            print("访问父类的私有属性 %d" % self.__num2)
    
            # 访问父类的私有方法
            self.test()
    
    a = A()
    b = B()
    b.demo()  # 报错
    
    
    • 但是子类可以通过公有方法间接的来访问父类的私有属性;
    class A:
        def __init__(self):
            self.__num2 = 33
    
        def __test(self):
            print("__num2 = %d" % self.__num2)
    
        def test(self):
            # 访问自己类的 私有属性
            print("私有属性__num2 = %d" % self.__num2)
            # 访问自己类的 私有方法
            self.__test()
    
    
    class B(A):
        def demo(self):
            self.test()  # 通过访问公共方法 test来间接访问 私有属性
    
    b = B()
    b.demo()  # 报错
    
    
    • 多继承(Java中使用的是接口)
    class A:
        def test_a(self):
            print("A类中的test_a方法!")
    
    
    class B:
        def test_b(self):
            print("B类中的test_b方法!")
    
    
    class C(A, B):
        pass
    
    c = C()
    c.test_a()
    c.test_b()
    
    • 注意,使用多继承的时候,如果两个父类中有相同的方法,尽量避免使用多继承, 避免产生混淆。可以使用__mro__(方法搜索顺序)用于在多继承时,判断方法、属性的调用路径;
    class A:
        def test1(self):
            print("A类中的test_1方法!")
    
        def test2(self):
            print("A类中的test_2方法!")
    
    
    class B:
        def test1(self):
            print("B类中的test_1方法!")
    
        def test2(self):
            print("B类中的test_2方法!")
    
    
    class C(A, B):
        pass
    
    c = C()
    c.test1()
    c.test2()
    print(C.__mro__)  # 输出C的继承路径
    
    

    输出:
    在这里插入图片描述

    • 新式类(python3)与旧式类(python2)
      在这里插入图片描述

    • 多态

    案例: 人和普通狗和哮天犬玩耍

    class Dog(object):
        def __init__(self, name):
            self.name = name
    
        def game(self):
            print("%s 蹦蹦跳跳的玩耍..." % self.name)
    
    
    class XiaoTianQuan(Dog):
        def game(self):
            print("%s 飞到天上玩耍.." % self.name)
    
    
    class Person(object):
        def __init__(self, name):
            self.name = name
    
        def play_with_dog(self, dog):
            print("%s 和 %s 一起玩耍..." % (self.name, dog.name))
            dog.game()
    
    p = Person("小明")
    
    dog = Dog("旺财")
    p.play_with_dog(dog)
    
    dog = XiaoTianQuan("哮天犬")
    p.play_with_dog(dog)
    

    输出:

    小明 和 旺财 一起玩耍...
    旺财 蹦蹦跳跳的玩耍...
    小明 和 哮天犬 一起玩耍...
    哮天犬 飞到天上玩耍..
    
    • 类的结构

    使用类名()创建对象,创建对象的动作分两步:

    • ①在内存中为对象分配空间;
    • ②调用初始化方法__init__为对象初始化;

    在这里插入图片描述

    • 类也是一个特殊的对象

    • 在这里插入图片描述

    • 属性的获取机制
      在这里插入图片描述

    class Tool(object):
        count = 0  # 这个是类属性
    
        def __init__(self, name):
            self.name = name
            Tool.count += 1  # 统计创建了多少个实例方法
    
    
    tool1 = Tool("斧头")
    tool2 = Tool("榔头")
    tool3 = Tool("水桶")
    print(Tool.count)  # 3
    
    # 也可以查看对象的count属性 -- > 属性的获取机制
    print(tool3.count)  # 3
    
    
    • 定义类属性和类方法
      在这里插入图片描述
      代码:
    class Tool(object):
    
        count = 0
    
        @classmethod
        def show_tool_count(cls):  # 类方法
            print("工具对象的数量 %d " % cls.count)   # 这个和self类似,取的是类内部的属性和方法
    
        def __init__(self, name):
            self.name = name
            Tool.count += 1
    
    
    tool1 = Tool("斧头")
    tool2 = Tool("榔头")
    tool3 = Tool("扳手")
    Tool.show_tool_count()  # 3
    
    • 静态方法
      在这里插入图片描述
    class Dog(object):
    
        @staticmethod
        def run():  # 注意这里第一个参数不需要self或者cls
            print("狗在跑...")
    
    
    # 调用的方式和类方法的方式一样 通过 类名.静态方法 调用静态方法
    Dog.run()
    
    • 三种方法(静态方法、类方法、实例方法)的综合使用(注意: 如果既要访问类属性,又要访问实例属性,就定义实例方法);
    class Game(object):
        top_score = 0
    
        def __init__(self, player_name):
            self.player_name = player_name
    
        @staticmethod
        def show_help():  # 静态方法
            print("游戏帮助信息..")
    
        @classmethod
        def show_top_score(cls):  # 类方法
            print("目前为止的最高分 %d" % cls.top_score)
    
        def start_game(self):
            print("%s 开始游戏了..." % self.player_name)
    
    
    Game.show_help()
    Game.show_top_score()
    game = Game("小明")
    game.start_game()
    
    • 单例模式以及__new__方法
      在这里插入图片描述
    class MusicPlayer:
        def __new__(cls, *args, **kwargs):  # 重写父类的__new__方法,必须返回
            print("创建对象,分配空间")
            # 为对象分配空间
            instance = super().__new__(cls)  # 因为__new__方法是一个静态方法,所以要传递cls关键字 (如果是类方法就不需要)
            # 一定要返回,不然就不能分配空间,创建的对象就为None
            return instance
    
        def __init__(self):
            print("播放器初始化")
    
    player = MusicPlayer()
    print(player)
    

    输出:

    创建对象,分配空间
    播放器初始化
    <__main__.MusicPlayer object at 0x7f47f2bd09b0>
    

    如果只重写__new__方法,没有返回相关的引用,创建的对象就为None。

    class MusicPlayer:
        def __new__(cls, *args, **kwargs):  # 重写父类的__new__方法,必须返回
            print("创建对象,分配空间")
    
        def __init__(self):
            print("播放器初始化")
    
    player = MusicPlayer()
    print(player)
    

    输出:

    创建对象,分配空间
    None
    
    • 实现单例模式
    class MusicPlayer(object):
        instance = None  # 类实例变量
        
        def __new__(cls, *args, **kwargs):  
    
            if cls.instance is None:
                cls.instance = super().__new__(cls)
    
            return cls.instance
    
    player1 = MusicPlayer()
    player2 = MusicPlayer()
    print(player1)  # <__main__.MusicPlayer object at 0x7fd7b631a978>
    print(player2)  # <__main__.MusicPlayer object at 0x7fd7b631a978> 和上面的一样
    
    • 上面的单例模式虽然__new__方法只会执行一次,但是__init__还是会执行多次,如何只让初始化只执行一次呢,可以定义一个类变量记录;
    class MusicPlayer(object):
        instance = None  # 类实例变量
        init_flag = False
    
        def __new__(cls, *args, **kwargs):
    
            if cls.instance is None:
                cls.instance = super().__new__(cls)
    
            return cls.instance
    
        def __init__(self):
    
            if MusicPlayer.init_flag:  # 已经执行过
                return
            print("初始化播放器")
            MusicPlayer.init_flag = True
    
    
    player1 = MusicPlayer()
    player2 = MusicPlayer()
    print(player1)
    print(player2)
    

    异常

    • 异常的语法结构
      在这里插入图片描述

    • 异常基本语法以及指定异常;

    try:
        num = int(input("请输入: "))
        res = 8 / num
        print(res)
    except ValueError:
        print("请输入数字!")
    except ZeroDivisionError:
        print("除0错误!")
    
    
    • 未知错误的异常处理代码演示;
    try:
        num = int(input("请输入: "))
        res = 8 / num
        print(res)
    except ValueError:
        print("请输入数字!")
    except Exception as result:
        print("未知错误 %s" % result)
    else:  # 注意这个是没有发生异常才会执行
        print("尝试成功!")
    finally:
        print("无论是否发生异常都执行的代码!")
    
    
    print("*" * 50)
    

    测试:

    请输入: 0
    未知错误 division by zero
    无论是否发生异常都执行的代码!
    **************************************************
    
    • 和Java一样,也有异常的传递性;
    def demo1():
        return int(input("请输入一个数: "))
    
    def demo2():
        demo1()
    
    try:
        demo2()
    except Exception as result:
        print("未知错误 %s" % result)
    
    

    测试:

    请输入一个数: a
    未知错误 invalid literal for int() with base 10: 'a'
    
    • 类似Java中的throw关键字,raise抛出异常对象;
    def input_password():
        pwd = input("请输入密码: ")
        if len(pwd) >= 6:
            return pwd
        raise Exception("密码长度小于8...")
    
    
    try:
        input_password()
    except Exception as result:
        print(result)
    

    运行结果:

    请输入密码: sdf
    密码长度小于8...
    

    模块、包

    • dir()内置函数可以查看一个模块里面的所有函数名称;
    • 导入模块的时候可以使用as关键字来给模块起一个别名(别名最好使用大驼峰命名法);
    • from import只导入部分工具,这种方式在调用具体的函数的时候不需要指定模块名.来调用;
    • 如果使用from import导入的模块有两个相同的工具(函数),则后导入的会覆盖前面导入的函数;如果确实想要都用到这两个相同名字的函数,可以使用起别名的方式解决;
    from python.exception.测试模块1 import say_hello as Moudel_say_hello
    from python.exception.测试模块2 import say_hello
    
    say_hello()  # 调用的是模块2的say_hello()
    Moudel_say_hello()  # 调用的是模块1的say_hello()
    
    • from import *的导入方式,这样和直接import 模块名看似是一样的,但是这种方式和from import一样,调用的时候不需要指定 模块名.,还是很方便的,但是开发中不推荐使用,因为有可能多个模块之间有相同的函数,这样也会导致覆盖的问题;
    • 给文件起名千万不要和系统的文件模块名字相同,因为搜索模块的顺序是先从当前目录下搜索模块,最后才是python解释器中的模块;
      在这里插入图片描述
    import random  # 同一个目录下不要有 random.py这个文件 ,不然就会先导入同目录下的,而不会导入python库中的
    
    print(random.__file__)  
    num = random.randint(0, 10)
    print(num)
    
    • __name__属性以及导入模块和测试的问题
      在这里插入图片描述

    例如在python/exception包下面有两个文件测试模块3.pypy10___name__属性的使用.py两个文件:
    py10___name__属性的使用.py代码如下:

    def say_hello():
        print("你好!")
    
    
    def main():
        say_hello()  # 测试
    
    
    if __name__ == "__main__":  # 如果不加上这个,导入这个模块的时候就会从上到下依次执行代码
        print(__name__)
        print("小明开发的模块!")
        main()
    

    测试模块3.py文件:

    import python.exception.测试模块3
    
    print("*" * 5)
    

    运行结果不会输出py10___name__属性的使用.py中的测试代码。

    • 包的概念: ①包是含有多个模块的特殊目录;②包下有一个__init__.py文件;
    • 在开发中,希望导入一个包,这个包中有多个模块,这时要使用包中的某个模块,需要在__init__.py中使用from . import 模块名的方式"注册"这个模块,别人才能使用这个模块;
      在这里插入图片描述

    例如:
    python/py_message包下面有三个文件: __init__.pysend_message.pyreceive_message.py三个文件,外界想使用后面两个文件: 则三个文件的代码如下 :
    __init__.py文件:

    from . import send_message
    from . import receive_message
    

    send_message.py文件:

    def send(text):
        print("正在发送 %s" % text)
    

    receive_message.py文件:

    def receive():
        return "这是来自 100XX的短信!";
    

    测试文件(和上面三个文件不在同一个包下):

    import python.py_message  # 导入的不是一个模块,而是一个包
    
    python.py_message.send_message.send("hello")
    txt = python.py_message.receive_message.receive()
    print(txt)
    
    • 制作发布压缩包三个步骤: ①创建setup.py文件,关于这个文件格式看官方文档;②构建模块,在终端执行python3 setup.py build;③生成发布压缩包,在终端执行python3 setup.py sdist

    • 安装模块: 可以将包中的模块安装到python系统中,只需要两步: ①解压 tar -zxvf 压缩包名.tar.gz;②安装sudo python3 setup.py install

    • 卸载模块: 直接在安装的目录删除即可(python安装的目录的模块下);

    • 安装第三方的包: sudo pip3 installl ...


    文件

    • 文件的存储方式
      在这里插入图片描述
    • 文件基本操作(python中是一个函数(open)+三个方法)
      在这里插入图片描述
    • read方法
      在这里插入图片描述
    # 1. 打开文件 获取文件对象
    file = open("README")
    
    # 2. 读取文件 (默认情况下读取文件的所有内容)
    txt = file.read()
    print(txt)
    
    # 3. 关闭文件
    file.close()
    
    • 关于文件指针的概念,在读取文件的时候,默认文件指针在文件的开始,在读取文件的时候会不断的移动,读取完之后到达文件的末尾。所以,如果使用read()读取了一次文件之后,再读取一次就不能读取到数据了;
    file = open("README")
    txt = file.read()
    print(txt)
    print(len(txt))
    
    print("*" * 40)
    
    print(file.read())  # 再次读取,因为文件指针已经移动到文件的末尾,所以读取不到
    # 3. 关闭文件
    file.close()
    

    输出:

    hello
    hello
    11
    ****************************************
    
    • 读取文件的方式
      在这里插入图片描述
    file = open("README", "w")  # w代表的是写入文件(覆盖)  a代表的是追加
    
    file.write("write hello to README")
    
    file.close()
    
    • 分行读取文件 : readline : 用来读取大文件的正确姿势。(read方法默认是直接读取整个文件)。readline每次读取一行之后,就会将文件指针往下移动一行;
    file = open("README")
    
    while True:
        txt = file.readline()
        if not txt:
            break
        print(txt, end="")  # 因为读取的时候以及读取了一个空行,这里就输出空行了
    
    file.close()
    
    • 文件复制案例(小文件)
    file_read = open("README")
    file_write = open("README[复件]", "w")
    
    text = file_read.read()
    file_write.write(text)
    
    file_read.close()
    file_write.close()
    
    • 大文件复制
    file_read = open("README")
    file_write = open("README[复件]", "w")
    
    while True:
        text = file_read.readline()
        if not text:  # 注意判断一下
            break
        file_write.write(text)
    
    file_read.close()
    file_write.close()
    
    
    • OS模块的命令使用
      在这里插入图片描述
    • python2也支持中文,只需要在py文件的行首增加一行代码# *-* coding:utf-8 *-*即可(python2默认使用的是ascii码编码);
    • 指定了上面的格式之后,如果遍历字符串,还是会乱码,处理的方式是在字符串前面加上一个u,例如str = u"hello",意思就是按照utf-8编码格式处理;
    • eval()函数,会将字符串的内容当做表达式处理(python语句)但是不要滥用这个函数,这个函数可以被注入内容(类似sql注入),例如输入__import__('os').system.('ls')

    展开全文
  • Python基础入门笔记(一)

    万次阅读 多人点赞 2018-09-16 09:51:37
    有关 Python: “人生苦短,我用PythonPython的设计哲学是“优雅”、“明确”、“简单”。 一、基础(变量和字符串) 首先:Python 每个语句结束可以不写分号 ;, 如 print('hello') 打印 hello 1、变量...

    前言(认识Python)

    既然学习 Python,那么至少得了解下这门语言,知道 Python 代码执行过程吧。Python 的历史有兴趣的百度百科下就有,这个不多说了。

    1、我们先来了解下什么是解释型语言和编译型语言?

    计算机是不能够识别高级语言的,所以当我们运行一个高级语言程序的时候,就需要一个“翻译机”来从事把高级语言转变成计算机能读懂的机器语言的过程。这个过程分成两类,第一种是编译,第二种是解释。

    编译型语言在程序执行之前,先会通过编译器对程序执行一个编译的过程,把程序转变成机器语言。运行时就不需要翻译,而直接执行就可以了。最典型的例子就是 C 语言。

    解释型语言就没有这个编译的过程,而是在程序运行的时候,通过解释器对程序逐行作出解释,然后直接运行,最典型的例子是 Ruby。

    通过以上的例子,我们可以来总结一下解释型语言和编译型语言的优缺点,因为编译型语言在程序运行之前就已经对程序做出了“翻译”,所以在运行时就少掉了“翻译”的过程,所以效率比较高。但是我们也不能一概而论,一些解释型语言也可以通过解释器的优化来在对程序做出翻译时对整个程序做出优化,从而在效率上超过编译型语言。

    此外,随着 Java 等基于虚拟机的语言的兴起,我们又不能把语言纯粹地分成解释型和编译型这两种。用 Java 来举例,Java 首先是通过编译器编译成字节码文件,然后在运行时通过解释器给解释成机器文件。所以我们说 Java 是一种先编译后解释的语言。再换成 C#,C# 首先是通过编译器将 C# 文件编译成 IL 文件,然后在通过 CLR 将 IL 文件编译成机器文件。所以我们说 C# 是一门纯编译语言,但是 C# 是一门需要二次编译的语言。同理也可等效运用到基于 .NET 平台上的其他语言。

    2、那么 Python 到底是什么?

    其实 Python 和 Java、C# 一样,也是一门基于虚拟机的语言,我们先来从表面上简单地了解一下 Python 程序的运行过程。

    当我们在命令行中输入 python hello.py 时,其实是激活了 Python 的“解释器”,告诉“解释器”:你要开始工作了。可是在“解释”之前,其实执行的第一项工作和 Java 一样,是编译。

    熟悉 Java 的读者可以想一下我们在命令行中如何执行一个 Java 的程序:

    javac hello.java
    java hello

    只是我们在用 Eclipse 之类的 IDE 时,将这两部给融合成了一部而已。其实 Python 也一样,当我们执行python hello.py时,它也一样执行了这么一个过程,所以我们应该这样来描述 Python,Python 是一门先编译后解释的语言。

    3、简述 Python 的运行过程

    在说这个问题之前,我们先来说两个概念,PyCodeObject 和 pyc 文件。

    我们在硬盘上看到的 pyc 自然不必多说,而其实 PyCodeObject 则是 Python 编译器真正编译成的结果。我们先简单知道就可以了,继续向下看。

    当 Python 程序运行时,编译的结果则是保存在位于内存中的 PyCodeObject 中,当 Python 程序运行结束时,Python 解释器则将 PyCodeObject 写回到 pyc 文件中。

    当 Python 程序第二次运行时,首先程序会在硬盘中寻找 pyc 文件,如果找到,则直接载入,否则就重复上面的过程。

    所以我们应该这样来定位 PyCodeObject 和 pyc 文件,我们说 pyc 文件其实是 PyCodeObject 的一种持久化保存方式。

    更详细内容参考:说说Python程序的执行过程

    最后:

    • “人生苦短,我用Python”

    • Python 的设计哲学是“优雅”、“明确”、“简单”。

    一、变量和字符串

    首先:Python 每个语句结束可以不写分号 ;, 如 print('hello') 打印 hello

    1.1 变量

    有过编程基础的话,变量就不用多说了。

    变量的命名法:

    • 驼峰式命名法
    • 帕斯卡命名法

    1.2 字符串

    1、基本介绍

    单引号 ' '或者双引号 " " 都可以,再或者 ''' ''' 三个引号,其中三个引号被用于过于长段的文字或者是说明,只要是三引号不完你就可以随意换行写下文字。

    ①字符串直接能相加,如:

    str1 = 'hi'
    str2 = 'hello'
    print(str1 + str2)

    运行结果:

    hi jaybo

    ②字符串相乘,如:

    string = 'bang!'
    total = string * 3 

    打印 total 结果:

    bang!bang!bang!

    2、字符串的分片与索引

    字符串可以通过 string[x] 的方式进行索引、分片。

    字符串的分片实际可以看作是从字符串中找出来你要截取的东西,复制出来一小段你要的长度,存储在另一个地方,而不会对字符串这个源文件改动。分片获得的每个字符串可以看作是原字符串的一个副本。

    先看下面这段代码:

    name = 'My name is Mike'
    print(name[0])
    'M'
    print(name[-4])
    'M'
    print(name[11:14]) # from 11th to 14th, 14th one is excluded
    'Mik'
    print(name[11:15]) # from 11th to 15th, 15th one is excluded
    'Mike'
    print(name[5:])
    'me is Mike'
    print(name[:5])
    'My na'

    如果感到困惑话,可以对照如下表格理解和分析:

    :两边分别代表着字符串的分割从哪里开始,并到哪里结束。

    name[11:14]为例,截取的编号从第11个字符开始,到位置为14但不包含第14个字符结束。而像name[5:]这样的写法代表着从编号为5的字符到结束的字符串分片。相反,name[:5]则代表着从编号为0的字符开始到编号为5但包含第5个字符分片。可能容易搞混,可以想象成第一种是从5到最后面,程序员懒得数有多少个所以就省略地写,第二种是从最前面到5,同样懒得写0,所以就写成了[:5]

    3、字符串的方法

    • replace 方法:第一个参数表示被替代部分,第二个参数表示替代成怎样的字符串。

    • 字符串填空,如:

      city = input("write the name of city:"")
      url = "http://apistore.baidu.com/mri.../weather?citypiny={}.format(city)

    4、问题

    问题1:

    num = 1
    string = '1'
    print(num + string)

    上面代码将出错?

    解释:整数型不能和字符串直接相加。可以先把该字符串转为整数型,再相加,即 int(string)

    num = 1
    string = '1'
    print(num + int(string))

    二、函数

    举些你可能已经使用过的函数例子:

    判断数据类型:type(str) 
    字符串类型数据转为整数型:int(str)
    ...

    通过观察规律不难发现,Python 中所谓的使用函数就是把你要处理的对象放到一个名字后面的括号就可以了。简单的来说,函数就是这么使用,可以往里面塞东西得到处理结果。这样的函数在 Python 中还有这些:

    以 Python3.5 版本为例,一个有 68 个这样的函数,它们被称为内建函数。这里內建的是指这些函数为安装好了 Python 就可以使用。

    2.1 函数格式

    定义函数的格式:

    其中,defreturn关键字

    注意: 函数缩进后面的语句被称为是语句块,缩进是为了表名语句的逻辑与从属关系。缩进这个问题不能忽视,否则会导致代码无法成功运行,这里需要特别注意。

    2.2 函数参数

    ①位置参数,举例,看代码:

    def trapezoid_area(base_up, base_down, height):
        return 1/2 * (base_up + base_down) * height

    接下来我们开始调用该函数:

    trapezoid_area(1,2,3)

    不难看出,填入的参数1,2,3分别对应着参数 base_up,base_down 和 height。这种传入参数的方式被称作为位置参数。

    ②关键词参数:在函数调用的时候,将每个参数名称后面赋予一个我们想要传入的值,如调用 fun1 函数时候:fun1(a=1, b=2, c=3)

    看下图:

    • 第一行的函数参数按照反序传入,因为是关键词参数,所以并不影响函数正常运作;
    • 第二行的函数参数反序传入,但是到了第三个却变成了位置函数,遗憾的是这种方式是错误的语法,因为如果按照位置来传入,最后一个应该是参数 height 的位置。但是前面 height 已经按照名称传入了值3,所以是冲突的。
    • 第三行的函数参数正序传入,前两个是以关键字的方式传入,最后一个以位置参数传入,但是位置参数不能再关键词参数后面,所以是错误的。
    • 第四行的函数参数正序传入,前两个是以位置的方式传入,最后一个以关键字参数传入,这个函数是可以正常运行的。

    ③不定长参数

    有时我们在设计函数接口的时候,可会需要可变长的参数。也就是说,我们事先无法确定传入的参数个数。

    Python 提供了一种元组的方式来接受没有直接定义的参数。这种方式在参数前边加星号 * 。如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。例如:

    def print_user_info( name ,  age  , sex = '男' , * hobby):
        # 打印用户信息
        print('昵称:{}'.format(name) , end = ' ')
        print('年龄:{}'.format(age) , end = ' ')
        print('性别:{}'.format(sex) ,end = ' ' )
        print('爱好:{}'.format(hobby))
        return;
    
    # 调用 print_user_info 函数
    print_user_info( '小明' , 25, '男', '打篮球','打羽毛球','跑步')

    输出的结果:

    昵称:小明 年龄:25 性别:男 爱好:('打篮球', '打羽毛球', '跑步')

    通过输出的结果可以知道,* hobby 是可变参数,且 hobby 其实就是一个 tuple (元祖)。

    可变长参数也支持关键参数,没有被定义的关键参数会被放到一个字典里。这种方式即是在参数前边加 **,更改上面的示例如下:

    def print_user_info( name ,  age  , sex = '男' , ** hobby ):
        # 打印用户信息
        print('昵称:{}'.format(name) , end = ' ')
        print('年龄:{}'.format(age) , end = ' ')
        print('性别:{}'.format(sex) ,end = ' ' )
        print('爱好:{}'.format(hobby))
        return;
    
    # 调用 print_user_info 函数
    print_user_info( name = '小明' , age = 25 , sex = '男', hobby = ('打篮球','打羽毛球','跑步'))

    输出的结果:

    昵称:小明 年龄:24 性别:男 爱好:{'hobby': ('打篮球', '打羽毛球', '跑步')}

    通过对比上面的例子和这个例子,可以知道,* hobby 是可变参数,且 hobby 其实就是一个 tuple (元祖),** hobby是关键字参数,且 hobby 就是一个 dict (字典)。

    ④ 只接受关键字参数

    关键字参数使用起来简单,不容易参数出错,那么有些时候,我们定义的函数希望某些参数强制使用关键字参数传递,这时候该怎么办呢?将强制关键字参数放到某个*参数或者单个*后面就能达到这种效果,比如:

    def print_user_info( name , *, age, sex = '男' ):
        # 打印用户信息
        print('昵称:{}'.format(name) , end = ' ')
        print('年龄:{}'.format(age) , end = ' ')
        print('性别:{}'.format(sex))
        return;
    
    # 调用 print_user_info 函数
    print_user_info( name = '小明' ,age = 25 , sex = '男' )
    
    # 这种写法会报错,因为 age ,sex 这两个参数强制使用关键字参数
    #print_user_info( '小明' , 25 , '男' )
    print_user_info('小明',age='22',sex='男')

    通过例子可以看,如果 age , sex 不适用关键字参数是会报错的。

    2.3 匿名函数

    有没有想过定义一个很短的回调函数,但又不想用 def 的形式去写一个那么长的函数,那么有没有快捷方式呢?

    ——答案是有的。

    Python 使用 lambda 来创建匿名函数,也就是不再使用 def 语句这样标准的形式定义一个函数。

    匿名函数主要有以下特点:

    • lambda 只是一个表达式,函数体比 def 简单很多。
    • lambda 的主体是一个表达式,而不是一个代码块。仅仅能在 lambda 表达式中封装有限的逻辑进去。
    • lambda 函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。

    基本语法:lambda [arg1 [,arg2,.....argn]]:expression

    示例:

    sum = lambda num1 , num2 : num1 + num2;
    print( sum( 1 , 2 ) )

    输出的结果: 3

    注意:尽管 lambda 表达式允许你定义简单函数,但是它的使用是有限制的。 你只能指定单个表达式,它的值就是最后的返回值。也就是说不能包含其他的语言特性了, 包括多个语句、条件表达式、迭代以及异常处理等等。

    匿名函数中,有一个特别需要注意的问题,比如,把上面的例子改一下:

    num2 = 100
    sum1 = lambda num1 : num1 + num2 ;
    
    num2 = 10000
    sum2 = lambda num1 : num1 + num2 ;
    
    print( sum1( 1 ) )
    print( sum2( 1 ) )

    你会认为输出什么呢?第一个输出是 101,第二个是 10001,结果不是的,输出的结果是这样:

    10001
    10001

    这主要在于 lambda 表达式中的 num2 是一个自由变量,在运行时绑定值,而不是定义时就绑定,这跟函数的默认值参数定义是不同的。所以建议还是遇到这种情况还是使用第一种解法。

    三、循环与判断

    3.1 布尔表达式和判断

    Python 中的布尔类型值:TrueFlase 其中,注意这两个都是首字母大写。

    但凡能够产生一个布尔值的表达式为布尔表达式

    1 > 2 # False
    1 < 2 <3 # True
    42 != '42' # True
    'Name' == 'name' # False
    'M' in 'Magic' # True
    number = 12
    number is 12 # True

    注1:不同类型的对象不能使用<><==>进行比较,却可以使用==!=

    注2:浮点类型和整数类型虽然是不同类型,但不影响比较运算。还有,不等于!= 可以写作<>

    话说,布尔类型可以比较吗?如:True > Flase,回答是可以的,TureFlase 对于计算机就像是 1 和 0 一样,所以结果是真,即True

    3.2 条件控制

    定义格式:

    用一句话该结构作用:如果…条件是成立的,就做…;反之,就做…

    所谓条件成立,指的是返回值为True的布尔表达式。

    3.3 循环

    ①for 循环

    把 for 循环所的事情概括成一句话就是:于…其中的每一个元素,做…事情。

    打印九九乘法表:

    for i in range(1, 10):
        for j in range(1, i+1):
            print('{}x{}={}\t'.format(i, j, i*j), end='')
        print()

    运行结果:

    1x1=1
    2x1=2   2x2=4
    3x1=3   3x2=6   3x3=9
    4x1=4   4x2=8   4x3=12  4x4=16
    5x1=5   5x2=10  5x3=15  5x4=20  5x5=25
    6x1=6   6x2=12  6x3=18  6x4=24  6x5=30  6x6=36
    7x1=7   7x2=14  7x3=21  7x4=28  7x5=35  7x6=42  7x7=49
    8x1=8   8x2=16  8x3=24  8x4=32  8x5=40  8x6=48  8x7=56  8x8=64
    9x1=9   9x2=18  9x3=27  9x4=36  9x5=45  9x6=54  9x7=63  9x8=72  9x9=81

    ②while 循环

    总结:只要…条件一成立,就一直做…

    在循环过程中,可以使用 break 跳过循环,使用 continue 跳过该次循环。

    在 Python 的 while 循环中,可以使用 else 语句,while … else 在循环条件为 false 时执行 else 语句块。如:

    count = 0
    while count < 3:
       print (count)
       count = count + 1
    else:
       print (count)

    运行结果:

    0
    1
    2
    3

    有 while … else 语句,当然也有 for … else 语句,for 中的语句和普通的没有区别,else 中的语句会在循环正常执行完(即 for 不是通过 break 跳出而中断的)的情况下执行,while … else 也是一样。如:

    for num in range(10,20):  # 迭代 10 到 20 之间的数字
       for i in range(2,num): # 根据因子迭代
          if num%i == 0:      # 确定第一个因子
             j=num/i          # 计算第二个因子
             print ('%d 是一个合数' % num)
             break            # 跳出当前循环
       else:                  # 循环的 else 部分
          print ('%d 是一个质数' % num)

    运行结果:

    10 是一个合数
    11 是一个质数
    12 是一个合数
    13 是一个质数
    14 是一个合数
    15 是一个合数
    16 是一个合数
    17 是一个质数
    18 是一个合数
    19 是一个质数

    四、数据结构

    Python 有四种数据结构,分别是:列表、字典、元组、集合。我们先从整体上认识一下这四种数据结构:

    list = [val1,val2,val3,val4] #列表
    dict = {key1:val1,key2:val2} #字典
    tuple = (val1,val2,val3,val4) #元组
    set = {val1,val2,val3,val4} #集合

    4.1 列表(List)

    1. 列表中的每个元素都是可变的;

    2. 列表中的元素是有序的,也就是说每个元素都有一个位置;

    3. 列表中可以容纳 Python 中的任何对象。如下:

      all_in_list = [
         1, #整数
         1.0, #浮点数
         'a word', #字符串
         print(1), #函数
         True, #布尔值
         [1,2], #列表中套列表
         (1,2), #元祖
         {'key':'value'} #字典
      ]

    另外,对于数据的操作,最常见的为增删改查。在此就省略了,网上找下相应函数练习下即可。

    4.2 字典(Dict)

    1. 字典中数据必须是以键值对的形式出现的;

    2. 逻辑上讲,键是不能重复的;

    3. 字典中的键(key)是不可变的,也就是无法修改的,而值(value)是可变的,可修改的,可以是任何对象。

      下面是个例子:

      NASDAQ_code = {
         'BIDU':'Baidu',
         'SINA':'Sina',
         'YOKU':'Youku'
      }

    一个字典中键与值并不能脱离对方而存在,如果你写成了 {'BIDU':} 会引发一个语法错误:invalid syntax

    如果试着将一个可变(mutable)的元素作为 key 来构建字典,比如列表:key_test = {[]:'a Test'} ,则会报一个错:unhashable type:'list'

    同时字典中的键值不会重复,即便你这么做,相同的键值也只能出现一次:a = {'key':123,'key':123}

    增删改查操作,在此省略了。

    备注:

    • 列表中用来添加多个元素的方法为extend,在字典中添加多个元素的方法为update()
    • 字典是不能切片的,即这样的写法是错误的:chart[1:4]

    4.3 元组(Tuple)

    元组可以理解为一个稳固版的列表,因为元组是不可以修改的,因此在列表中的存在的方法均不可以使用在元组上,但是元组是可以被查看索引的,方式和列表一样。

    letters = ('a, 'b', 'c', 'd')
    letters[0]

    相关的操作找代码练习下即可。

    4.4 集合(Set)

    集合则更接近数学上集合的概念。每一个集合中是的元素是无序的、不重复的任意对象,我们可以通过集合去判断数据的从属关系,有时还可以通过集合把数据结构中重复的元素减掉。

    集合不能被切片也不能被索引,除了做集合运算之外,集合元素可以被添加还有删除:

    a_set = {1,2,3,4}
    a_set.add(5)
    a_set.discard(5)

    4.5 数据结构的一些技巧

    4.5.1 多重循环

    如下:

    代码演示:

    for a, b in zip(num, str):
        print(b, 'is', a)

    4.5.2 推导式

    列表推导式的用法很好理解,可以简单地看成两部分。如下图:

    红色虚线后面的是我们熟悉的 for 循环的表达式,而虚线前面的可以认为是我们想要放在列表中的元素。

    代码演示:

    a = []
    for i in range(1, 11):
        a.append(i)

    可以换成列表解析的方式来写:

    b = [i for in i range(1, 11)]

    列表解析式不仅方便,并且在执行效率上要远远胜过前者。

    五、类的理解

    5.1 类的介绍

    类的定义:

    class CocaCola:
        formula = ['caffeine','sugar','water','soda']

    使用 class 来定义一个类,就如同创建函数时使用的 def 定义一个函数一样简单。如上你可以看到定义了名为 CocaCola 的类,接着在缩进的地方有一个装载着列表的变量的 formula,这个在类里面定义的变量就是类的变量,而类的变量有一个专有的术语,我们称之为类的属性。

    类的属性:

    • 类变量
    • 方法

    ①类的实例化:

    coke_for_me = CocaCola()
    coke_for_you = CocaCola()

    ②类变量属性的引用:CocaCola.formulacoke_for_me.formula

    类方法的使用:

    class CocaCola:
        formula = ['caffeine','sugar','water','soda']
        def drink(self):
            print('Energy!')
    coke = CocaCola()
    coke.drink()

    结果:

    Energy!

    5.2 self

    我想很多人会有关注到这个奇怪的地方——似乎没有派上任何用场的self参数。我们来说明下原理,其实很简单,我们修改下上面的代码:

    class CocaCola:
        formula = ['caffeine','sugar','water','soda']
        def drink(coke):    # 把self改为coke
            print('Energy!')
    coke = CocaCola()
    coke.drink()

    结果:

    Energy!

    怎么样,有些头绪了吧!这个参数其实就是被创建的实例本身。也就是将一个个对象作为参数放入函数括号内,再进一步说,一旦一个类被实例化,那么我们其实可以使用和与我们使用函数相似的方式:

    coke = CocaCola
    coke.drink() == CocaCola.drink(coke) #左右两边的写法完全一致

    被实例化的对象会被编译器默默地传入后面方法的括号中,作为第一个参数。上面两个方法是一样的,但我们更多地会写成前面那种形式。其实self这个参数名称是可以随意修改的(编译器并不会因此而报错)。

    和函数一样,类的方法也能有属于自己的参数,如下:

    class CocaCola:
        formula = ['caffeine','sugar','water','soda']
        def drink(self,how_much):
    
        if how_much == 'a sip':
            print('Cool~')
        elif how_much == 'whole bottle’:
            print('Headache!')
    ice_coke = CocaCola()
    ice_coke.drink('a sip')

    结果:

    Cool~

    5.3 魔术方法

    Python 的类中存在一些方法,被称为「魔术方法」,_init_()就是其中之一。

    class CocaCola():
        formula = ['caffeine','sugar','water','soda']
        def __init__(self):
            self.local_logo = '可口可乐'
        def drink(self): 
            print('Energy!')
    coke = CocaCola()
    print(coke.local_logo)

    作用:在创建实例之前,它做了很多事情。说直白点,意味着即使你在创建实例的时候不去引用 init_() 方法,其中的语句也会先被自动的执行。这给类的使用提供了极大的灵活性。

    class CocaCola:
        formula = ['caffeine','sugar','water','soda']
        def __init__(self,logo_name):
            self.local_logo = logo_name
        def drink(self):
            print('Energy!')
    coke = CocaCola('ݢݗݢԔ')
    coke.local_logo
    >>> 可口可乐

    有过面向对象编程经验很好理解了,也就是很多面向对象语言中的「构造函数」。

    5.4 类的继承

    如下代码:

    class CaffeineFree(CocaCola):
        caffeine = 0
        ingredients = [
            'High Fructose Corn Syrup',
            'Carbonated Water',
            'Phosphoric Acid',
            'Natural Flavors',
            'Caramel Color',
        ]
    coke_a = CaffeineFree('Cocacola-FREE')
    coke_a.drink()

    表示 CaffeineFree 继承了 CocaCola 类。

    类中的变量和方法可以被子类继承,但如需有特殊的改动也可以进行覆盖。

    Q1:类属性如果被重新赋值,是否会影响到类属性的引用?

    class TestA():
        attr = 1
    obj_a = TestA()
    
    TestA.attr = 24
    print(obj_a.attr)
    
    >>> 结果:24

    A1:会影响。

    Q2:实例属性如果被重新赋值,是否会影响到类属性的引用?

    class TestA:
        attr = 1
    obj_a = TestA()
    obj_b = TestA()
    
    obj_a.attr = 42
    print(obj_b.attr)
    
    >>> 结果:1

    A2:不会影响。

    Q3:类属性实例属性具有相同的名称,那么.后面引用的将会是什么?

    class TestA():
        attr =1
        def __init__(self):
            self.attr = 24
    
    obj_a = TestA()
    
    print(obj_a.attr)
    
    >>> 结果:24

    A3:类属性赋值后的值。

    总结:如图所示,Python 中属性的引用机制是自外而内的,当你创建了一个实例之后,准备开始引用属性,这时候编译器会先搜索该实例是否拥有该属性,如果有,则引用;如果没有,将搜索这个实例所属的类是否有这个属性,如果有,则引用,没有那就只能报错了。

    六、使用第三方库

    6.1 安装自己的库

    我们一般使用 pip 来进行第三方库的安装,那么自己的库要怎么安装呢?当然可以把自己的库提交到 pip 上,但是还要添加一定量的代码和必要的文件才行,在这里我们使用一个更简单的方法:
    1. 找到你的 Python 安装目录,找到下面的 site-packages 文件夹;
    2. 记住你的文件名,因为它将作为引用时的名称,然后将你写的 py 文件放进去。

    这个文件夹应该有你所安装的所有第三方库。如果你并不清楚你的安装路径,可以尝试使用如下方式搞清楚它究竟在哪里:

    import sys
    print(sys.path)

    打印出来的会是一个列表,列表中的第四个将是你的库安装路径所在,因此你也可以直接这么做:

    import sys
    print(sys.path[3])

    6.2 安装第三方库

    令人惊叹的第三方库

    如果用手机来比喻编程语言,那么 Python 是一款智能机。正如含量的手机应用出现在 iOS、Android 平台上,同样有各种各样的第三方库为 Python 开发者提供了极大的便利。

    当你想要搭建网站时,可以选择功能全面的 Django、轻量的 Flask 等 web 框架;当你想写一个小游戏的时候,可以使用 PyGame 框架;当你想做一个 爬虫时,可以使用 Scrapy 框架;当你想做数据统计分析时,可以使用 Pandas 数据框架……这么多丰富的资源可以帮助我们高效快捷地做到想做的事,就不需要再重复造轮子了。

    那么如何根据自己的需求找到相应的库呢?可以到 awesome-python.com 这个网站上按照分类去寻找,上面收录了比较全的第三方库。比如想要找爬出方面的库时,查看 Web Crawling 这个分类,就能看到相应的第三方库的网站与简介,可以进入库的网站查看更详细的介绍,并确认这个库支持的是 Python 2 还是 Python 3,不过绝大多数常用库已经都支持了这两者。另外也可以直接通过搜索引擎寻找。

    安装第三方库方式:

    ①最简单的方式:在 PyCharm 中安装

    1. 在 PyCharm 的菜单中选择:File –> Default Setting
    2. 搜索 project interpreter,选择当前 python 版本,点击“+”添加库
    3. 输入库的名称,勾选,并点击 Install Package

    在安装成功后, PyCharm 会有成功提示。也可以在 project interpreter 这个界面中查看安装了哪些库,点“-”号就可以卸载不再需要的库。

    ②最直接的方式:在终端/命令行中安装

    PyPI(Python Package Index)是 Python 官方的第三方库的仓库,PyPI 推荐使用 pip 包管理器来下载第三方库。

    1. 安装 pip

      在 Python 3.4 之后,安装好 Python 环境就可以直接支持 pip,你可以在终端/命令行里输入这句检查一下:pip --version (前提电脑 path 路径已经配置好了),如果显示 pip 版本,就说明 pip 已经成功安装了;如果发现没有安装,则根据不同系统如下方式安装:

    2. 使用 pip 安装库

      在安装好了 pip 之后,以后安装库,只需要在命令行里面输入:pip3 install PackageName(注:如果你想要安装到 Python 2 中,需要把 pip3 换成 pip)。补充:

      如果你安装了 Python 2 和 3 两种版本,可能会遇到安装目录的问题,可以换成:python3 -m pip install PackageName (注:如果你想安装到 Python2 中,需要把 Python3 换成 Python)

      如果遇到权限问题,可以输入:sudo pip install PackageName

      安装成功之后会提示:Successfully insyalled PackageName

      一些常用的 pip 指令:

      
      # pip 使用格式:pip <command> [options] package_name
      
      
      pip install package_name==1.9.2 # 安装指定版本的包
      pip install --upgrade package_name  # 更新指定的包
      pip uninstall package_name  # 卸载指定的包
      pip show package_name   # 查看所安装包的详细信息
      pip list    # 查看所有安装的包
      pip --help  # 查看帮助

    补充:如果下载很慢,可以考虑更改 pip 下载源。国内镜像有:

    # 国内常用的镜像
    http://pypi.douban.com/simple/            # 豆瓣
    http://mirrors.aliyun.com/pypi/simple/    # 阿里
    https://pypi.tuna.tsinghua.edu.cn/simple  # 清华
    http://pypi.mirrors.ustc.edu.cn/simple/   # 中国科学技术大学
    http://pypi.hustunique.com/simple/        # 华中理工大学

    更改方法:

    1. 临时使用,添加 -i--index 参数:pip install -i http://pypi.douban.com/simple/ flask
    2. Linux下永久生效的配置方法

      cd $HOME  
      mkdir .pip  
      cd .pip
      sudo vim pip.conf  
      
      
      # 在里面添加,trusted-host 选项为了避免麻烦是必须的,否则使用的时候会提示不受信任  
      
      [global]
      index-url=https://pypi.tuna.tsinghua.edu.cn/simple
      
      [install]
      trusted-host=pypi.tuna.tsinghua.edu.cn 
      disable-pip-version-check=true
      timeout = 6000 
    3. Windows 下永久生效的配置方法

      
      # a、进入如下目录(没有此目录或文件就自己创建下)
      
      C:\Users\username\AppData\Local\pip
      或
      C:\Users\username\pip
      
      
      # b、创建 “pip.ini” 文件(注意:以UTF-8 无BOM格式编码),添加如下内容
      
      [global]
      index-url=https://pypi.tuna.tsinghua.edu.cn/simple
      
      [install]
      trusted-host=pypi.tuna.tsinghua.edu.cn 
      disable-pip-version-check=true
      timeout = 6000 

    ③最原始的方式:手动安装

    进入 pypi.python.org,搜索你要安装的库的名字,这时候有 3 种可能:

    1. 第一种是 exe 文件,这种最方便,下载满足你的电脑系统和 Python 环境的对应的 exe,再一路点击 next 就可以安装。
    2. 第二种是 .whl 类文件,好处在于可以自动安装依赖的包。

      1. 到命令行输入pip3 install whell 等待执行完成,不能报错(Python 2 中要换成 pip)
      2. 从资源管理器中确认你下载的 .whl 类文件的路径,然后在命令行继续输入:cd C:\download,此处需要改为你的路径,路径的含义是文件所在的文件夹,不包含这个文件名字本身,然后再命令行继续输入:pip3 install xxx.whlxxx.whl 是你下载的文件的完整文件名。
    3. 第三种是源码,大概都是 ziptar.ziptar.bz2 格式的压缩包,这个方法要求用户已经安装了这个包所依赖的其他包。例如 pandas 依赖于 numpy,你如果不安装 numpy,这个方法是无法成功安装 pandas 的。

      1. 解压包,进入解压好的文件夹,通常会看见一个 setup.py 的文件,从资源管理器中确认你下载的文件的路径,打开命令行,输入:cd C:\download 此处需要改为你的路径,路径的含义是文件所在的文件夹,不包含这个文件名字本身
      2. 然后在命令行中继续输入:python3 setup.py install 这个命令,就能把这个第三方库安装到系统里,也就是你的 Python路径,windows 大概是在 C:\Python3.5\Lib\site-packages

      注:想要卸库的时候,找到 Python 路径,进入 site-packages 文件夹,在里面删掉库文件就可以了。

    本文内容大部分来源:

    展开全文
  • Python基础教程》---值得读几遍的Python入门书

    万次阅读 多人点赞 2018-08-04 12:21:36
    Python基础教程》看了三遍。第一遍囫囵吞枣、尝试写代码;第二遍重温,同步看《Python学习手册》、《Python Cookbook》,部分细节(如正则表达式)对照另两本书一起看,敲代码;第三遍仔细看了一遍,花了一个多月...

        《Python基础教程》看了三遍。第一遍囫囵吞枣、尝试写代码;第二遍重温,同步看《Python学习手册》、《Python Cookbook》,部分细节(如正则表达式)对照另两本书一起看,敲代码;第三遍仔细看了一遍,花了一个多月时间,每天晚上1~2个小时,收获很大。

    •         本书优点:简洁的讲了基本的内容后,提供10个编程例子练手。可分三部分:

           第一部分:基础,包括:基本语法--->抽象(函数,类)--->异常--->迭代-->标准库(包括正则表达式)。这些内容在《Python学习手册》中讲的非常详细,看起来会累;本书轻松一些。

           第二部分:和外界打交道,包括:文件、图形界面、数据库、网络编程,知识点对应后面10个例子。又讲到如何测试、打包、发布程序。讲的较为简单,可以在用到某个功能时再找资料。

           第三部分:实践。 20~29章,每章一个编程例子。学好Python语法,有了疑问:Python可以用来做什么?都说它很强大,强大在哪里?耐心琢磨、读懂10个例子后,对这两个问题有了感觉。

           这10个例子涉足:文本处理、利用图形创建PDF文件、XML生成网站、聊天工具(网络)、CGI技术、基于Web的论坛(CGI、数据库)、XML-RPC、GUI。例子虽然不是最新技术,但告诉了应用方向。第10个例子,看题目“DIY街机游戏”,就觉得很神奇,怎么开发一个像模像样的游戏?按照它的方法做一遍,也不是那么难。

           每个例子的组织很好:问题是什么-->有用的工具--->准备工作--->初次实现--->再次实现--->进一步探索。学好语法之后,我能笨拙、费力的用初次实现的方法,硬编码解决问题。而再次实现“如何将一个没有任何形式抽象(没有函数、类)的简单原型改进为一个增加了数个重要抽象特征的泛型系统”。再次实现的思路、设计很好,光学语法真的没法写出来,虽然有些例子的内容可能有点老,但思路值得学习。

    •        本书有意思的细节

            第1章:脚本的第一行:#!/usr/bin/env python,一直不知所以然。它叫“pound bang”或者“shebang”。作用是像运行其他程序(比如浏览器、文本编辑器)一样运行Python程序,而不需要显示使用Python解释器。

          第11章:包的概念,“为了将Python将其作为包对待,它必须包含一个命名为__init__.py的文件”。明白了我在写robotframework库的时候,每个库都包含一个__init__.py文件的原因。

           第18章,怎么用Python编写安装脚本,明白了安装的第三方库是怎么来的,为什么要输入“python setup.py”进行安装。

           另外,一些箴言也不错。“查看源代码(“使用源代码”,记得吗),可以了解程序的工作机制”(P436);“要记得Python的学习箴言:使用源代码(就是说要阅读能得到的所有代码)”。(P450)----计划开始读工作中用到的第三方库的代码。“如果读者能够掌握本章的某些概念,那么你的Python编程水平就会有很大程度的提高。使用手头上的标准库可以让Python变的无比强大”(P206)----需要好好学习应用《Python标准库》。

    •       本书的瑕疵

           有些地方讲的简单、晦涩,要费力才能理解,有几处费力了还是没有理解,但所幸这样的地方不多。瑕不掩瑜。

           八皇后问题真的很难理解,第三遍基本能够明白了,第一次时真是云里雾里。

           正则表达式的sub函数,也是对照了其他资料才明白的。P326“re.sub函数可以将一个函数作为第二个参数(替换式)。函数会被匹配的对象调用,并且它的返回值会被插入到文本中”。我认为“函数会被匹配的对象调用”应该是“函数会接受被匹配的对象作为参数”,这样才对。

            其他大概还有3、4个看不懂的小点。

           Ps.开始在工作中应用python,尝试到了它的好处。

    展开全文
  • Python入门系列教程-python基础

    千人学习 2019-12-02 10:11:55
    本课程完全基于最新版Python讲解,针对广大的Python爱好者与同学录制。通过本课程的学习,可以让同学们在学习Python的过程中少走弯路。整个课程以实例教学为核心,通过对大量丰富的经典实例的讲解。让同学们可以对...
  • 【详细】Python基础(一)

    千次阅读 多人点赞 2020-09-15 00:46:53
    Python基础语法2.1 基本语法 前言 人生苦短,我用Python 1. Python环境的搭建 解释器和开发集成环境pycharm的安装还是比较简单的。   1.1 python解释器的安装   (1)到官网下载python解释器 下载地址:...

    前言

    人生苦短,我用Python

    1. Python环境的搭建

    解释器和开发集成环境pycharm的安装还是比较简单的。
     

    1.1 python解释器的安装

     
    (1)到官网下载python解释器

    下载地址:https://www.python.org/downloads/release/python-372/

    在这里插入图片描述
    注释: 这个解释器是3.7.2版本的
     
     
    (2)开始安装python解释器

    安装解释器非常简单,选择Install Now, 在把下面的环境变量打上对勾就ok了。如下如所示

    在这里插入图片描述
     

    1.2 pycharm的安装

     
    工欲善其事,必先利其器。Pycharm是一种Python IDE(集成开发环境),带有一整套可以帮助用户在使用Python语言时 提高其效率的工具。 简单的说提高你写代码的速度,编写代码更爽更舒服。
     

    (1)到官网下载Pycharm

    下载地址:http://www.jetbrains.com/pycharm/download/#section=windows

    在这里插入图片描述
     

    小提示: Pythoncharm分为专业版(professional)和社区版(community)。专业版集成了一些框架和库,收费的,基础里用不到,社区版就够用了。
     
     
    (2)开始安装pycharm
    安装pycharm也非常简单,选好安装路径,我安装到D盘了。然后到达了如下图的界面,选择一个64位的桌面图标(shortcut),再选择一个.py的联想,如下图所示。

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

    2. Python基础语法

     

    2.1 基本语法

     
    直接上代码,一看就懂了

    # 这是一个输出语句
    print("Hello,World")
    """
    这是一个多行注释
    """
    
    '''
    这也是一个多行注释
    '''
    ====================================================================================
    # 定义变量,储存数据TOM
    my_name = 'TOM'
    print(my_name)
    
    # 定义变量,储存数据,这是一瓶冰红茶
    icdTea = '这是一瓶冰红茶'
    print(icdTea)
    
    

     

    2.2 数据类型

     
    来一个思维导图,简单明了

    在这里插入图片描述
    直接上代码,一看就懂了

    # 整型和浮点型
    num1 = 1
    num2 = 1.2
    print(type(num1))
    print(type(num2))
    
    # 这是一个字符串类型
    a = 'hello,world!'
    print(type(a))
    
    # 这是一个布尔类型
    b = True
    print(type(b))
    
    # 这是一个列表类型
    c = [10,20,30]
    print(type(c))
    
    # 这是一个元组类型
    d = (10,20,30)
    print(type(d))
    
    # 这是一个集合
    e = {10,20,30}
    print(type(e))
    
    # 这是一个字典
    f = {'name': 'TOM','age': 18}
    print(type(f))
    
    

    小提示:还有个复数类型,就是用于表示数学中的复数,用 real + imagej表示
     
     

    2.3 标识符与关键字

     
    这里不多说,跟C语言和Java中的知识都差不多一样,提几个需要注意的地方。
    标识符:
    (1)由数字、字母、下划线组成
    (2)不能数字开头
    (3)不能使用内置关键字
    (4)严格区分大小写
     
     

    2.4 格式化输出

     
    直接上代码,一看就懂

    age = 18
    name = 'TOM'
    weight = 75.5
    stu_id = 1
    
    print('今年我的年龄是%d' % age)
    print('我的名字叫%s' % name)
    print('我的体重是%.3f' % weight)
    print('我的体重是%03d' % stu_id)  # 不够三位,用0补全
    
    print('我的名字叫:%s ,我的年龄是:%d' % (name,age))
    print("我的名字叫:%s,我的年龄是:%d" % (name,age+1))  # 年龄加一岁
    
    print("我的名字叫:%s,今年的年龄是:%d,我的体重是:%s,我的学号是:%03d" % (name,age,weight,stu_id))
    
    ===========================================================================================
    
    name = "TOM"
    age = 18
    weight = 75.5
    
    # %s比较强大
    print('我的名字叫:%s,我的年龄是:%s,我的体重是:%s' % (name,age,weight))
    
    ===========================================================================================
    
    name = 'TOM'
    age = 16
    
    # 语法:f'{表达式}'
    # 这样的输出格式更加高效和简洁
    
    print(f'我的名字叫{name},我的年龄为{age}')
    
    

    小提示:

    (1)务必掌握这种输出格式f'{表达式}' ,这种的输出格式更加高效简洁。f-格式化字符串是Python3.6中新增的格式化方法,这种方法更简单易读。

    (2)常见的格式符号:%s (字符串) %d(有符号的十进制整数) %f(浮点数) %c(字符) 这几种是常见的格式符号,如果需要其他的再去查就好了。
     
     

    2.5 转义字符和print的结束符

     
    直接上代码,一看就懂
     

    print('hello world')
    print('hello\nworld')  # hello world直接换行输出
    print('\thello')    # 前面输出空格再输出hello
    
    =================================================================
    
    # 在python中,print()默认自带end='\n'这个换行结束符,用户可以按照需求更改结束符
    
    print('hello', end='\n')
    print('world')
    
    print('hello', end='\t')
    print('hello')
    
    print('hello', end='...')
    print('world')
    
    

    小提示:要记住print的结束符这个小知识点。
     
     

    2.6 输入与数据类型转换

     
    直接上代码,一看就懂
     

    passward = input('请输入您的密码:')
    print(f'您输入的密码是:{passward}')
    
    # input接收到的数据类型都是字符串
    print(type(passward))
    
    ====================================================================================
    
    num = input("请输入一个数字:")
    print(num)
    print(type(num))
    
    # 强制转换为int类型
    print(type(int(num)))
    print(type(int(num)))
    
    ===================================================================================
    
    '''
    因为得到数据类型并不是程序想要的数据类型,这个时候需要借助数据类型转换的函数来转换
    '''
    num = 1
    str1 = '10'
    
    # 1.将数据转换成浮点类型 float()
    print(type(float(num)))
    print(float(num))
    print(float(str1))
    
    # 2. 将数据转换成字符串型 str()
    print(type(str(num)))
    
    # 3. 序列转换成元组 tuple()
    list1 = [10,20]
    print(type(list1))
    print(type(tuple(list1)))
    print(tuple(list1))  	 # (100, 200)
    
    # 4. 将一个元组转换成序列 list()
    t1 = (100,200)
    print(list(t1)) 		# [100, 200]
    
    # 5. eval() 计算在字符串中的有效Python表达式,并返回一个表达式。把字符串中的数据转换成他原本的类型
    str3 = '1'
    str4 = '2.1'
    str5 = '(10,20)'
    str6 = '[10,20]'
    print(type(eval(str3)))   # <class 'int'>
    
    

     
     

    2.7 复合赋值运算符和逻辑运算符

     
    总结几个常用算数运算符
     
    (1)**      返回a的b次幂,比如 2 ** 3,结果位8

    (2)%      取余

    (3)//      取整除,返回商的整数部分。
     
    总结几个常用复合赋值运算符
     
    直接上代码,一看就懂
     

    a = 10
    a += 1
    print(a)  # 11
    
    b = 10
    b *= 3
    print(b)  # 30
    
    # 注意:先算复合赋值运算符右侧的表达式,算复合赋值运算
    c = 10
    c += 1 + 2
    print(c)  # 13
    
    # 测试
    d = 10
    d *= 1 + 2
    print(d)  	# 30 说明先算复合赋值运算符右侧的表达式,再算复合赋值运算
    
    =====================================================================
    
    # 逻辑运算符的运用
    
    a = 0
    b = 1
    c = 2
    
    # 1.and
    print((a < b) and (a < c))   # True
    print(a > b and a < c)		# False
    
    # 2.or
    print(b > c or a < c)  # True
    
    # 3.not
    print(not a < b)	# False
    
    # 程序员的习惯
    # 加小括号为了避免歧义,增加优先级
    

     
     

    3. Python常用语句

    3.1 判断语句(if语句、if-else语句、if-elif语句)

    直接上代码,一看就懂

    if True:
        print('条件成立了')
    # 下面的代码没有缩进到if语句块,所以和if条件无关
    print('这个代码执行吗?')
    
    =================================================================
    
    age = 20
    if age >= 18:
        print('已经成年可以上网')
    
    # 注意:不缩进的语句,跟if语句没有关系了。
    print('系统关闭')
    
    ================================================================
    
    # 注意:input接受用户输入的数据是字符串类型,这时需要转换为int类型才能进行判断
    age =int( input('请输入您的年龄:'))
    if age >= 18:
        print(f'您输入的年龄是{age},已经成年可以上网')
        
    ================================================================
    
    age =int( input('请输入您的年龄:'))
    if age >= 18:
        print(f'您输入的年龄是{age},已经成年可以上网')
    else:
        print(f'你输入的年龄是{age},小朋友,回家写作业去')
    
    ----------------------------------------------------------------
    
    age = int(input('请输入您的年龄'))
    if age < 18:
        print(f'您输入的年龄是{age},童工')
    elif (age >= 18) and (age <= 60):
        print(f'您输入的年龄是{age},合法')
    elif age > 60:
        print(f'您输入的年龄是{age},退休')
    
    -----------------------------------------------------------------
    
    age = int(input('请输入您的年龄'))
    if age < 18:
        print(f'您输入的年龄是{age},童工')
    #  条件的简化写法
    elif 18 <= age <= 60:
        print(f'您输入的年龄是{age},合法')
    elif age > 60:
        print(f'您输入的年龄是{age},退休')
    
    

    3.2 判断语句(if嵌套)

    直接上代码

    # if嵌套坐公交
    
    money = 1
    seat = 1
    
    if money == 1:
        print('土豪,请上车')
        # 判断是否能坐下
        if seat == 1:
            print('有空做,请坐下')
        else:
            print('没有空做,请等着....')
    else:
        print('没钱,不让上车')
    
    
    

     

    3.3 判断语句(if 综合案例)

     
    直接上代码

    # 猜拳游戏
    import random
    
    player = int(input('请出拳:0--石头;1--剪刀;2--布'))
    # computer = 1
    computer = random.randint(0,2)
    if ((player == 0) and (computer == 1)) or ((player == 1) and (computer == 2)) or ((player == 2) and (computer == 0)):
        print('玩家获胜,哈哈哈 ')
    elif player == computer:
        print('平局')
    else:
        print('电脑获胜')
    
    ================================================================================
    
    # 随机数的使用
    
    '''
    步骤:
        1.导入模块
        import random
        2.使用这个模块中的功能
        random.randint
    '''
    import random
    num = random.randint(0,2)
    print(num)
    
    ================================================================================
    
    # 三目运算符
    a = 1
    b = 2
    c = a if a > b else b
    print(c)
    
    aa = 10
    bb = 6
    cc = aa - bb if aa > bb else bb - aa
    print(cc)
    
        
    

     

    3.4 循环语句(while循环)

    直接看个栗子就能上手使用while循环

    # 1-100 累加和
    i = 1
    result = 0
    while i <= 100:
        result += i
        i += 1
    
    print(result)
    

    3.5 循环语句(while循环嵌套)

    
    # 重复打印5行星星
    
    j = 0
    while j < 5:
        # 一行星星的打印
        i = 0
        while i < 5:
            # 一行内的星星不能换行,取消print默认结束符\n
            print('*', end='')
            i += 1
        # 利用空的print来进行换行
        print()
        j += 1
    
    ============================================================
    
    # 打印三角形,每行星星的个数和行号数相等
    # j表示行号
    j = 0
    while j < 5:
        # 一行星星的打印
        i = 0
        while i <= j:
            # i表示每行里面星星的个数,这个数字要和行号相等所以i要和j联动
            print('*', end='')
            i += 1
        # 利用空的print来进行换行
        print()
        j += 1
    
    =============================================================
    
    j = 1
    while j <= 9:
        # 一行表达式的开始
        i = 1
        while i <= j:
            print(f'{i} * {j} = {i*j} ' , end='\t')
            i += 1
        # 一行表达式的结束
        print()  # 自带换行符
        j += 1
        
    

    3.6 循环语句(while…else)

    
    '''
    所谓else指的是循环正常结束之后要执行的代码,
    即如果是break终止循环的情况,else下方缩进的代码将不执行。
    '''
    
    i = 1
    while i <= 5:
        if i == 3:
            break
        print('媳妇我错了')
        i += 1
    else:
        print('媳妇原谅我了,真开心呐')
    
    ===================================================================
    
    """
    因为continue是退出了当前一次循环,继续下一次循环,所以改循环在continue控制下
    是可以正常结束的,当循环结束后,则执行了else缩进的代码。
    """
    i = 1
    while i <= 5:
        if i == 3:
            # 切记在执行continue之前,一定要改变计数器。否则就会陷入死循环
            i += 1
            continue
        print('媳妇我错了')
        i += 1
    else:
        print('媳妇原谅我了,真开心呐')
    
        
    

    3.7 循环语句(for、for…else)

    
    str1 = 'ilovepython'
    for i in str1:
        # 当某些条件成立,退出循环  条件:i取到字符e的时候退出循环
        if i == 'e':
            # continue
            break
        print(i)
       
    ======================================================================
    
    所谓else指的是循环正常结束之后要执行的代码,
    str1 = 'ilovepython'
    for i in str1:
        print(i)
    else:
        print('循环正常结束执行的else代码')
        
    

    4. 字符串

    4.1 字符串的使用

    # 字符串的使用区别
    
    a = 'hello' \
        ' world'
    print(a)   # 输出一行 hello world
    
    c = '''hello 
    world'''
    print(type(c))
    print(c)       # 换行输出hello world
    
    
    d = """hello 
    world"""
    print(type(d))  # <class 'str'>
    print(d)        # 会直接换行输出
    
    # 打印 I'm Tom,使用单引号,必须使用转移字符,把他转义过去
    e = 'I\'m Tom'
    print(e)
    
    # 要是有单引号出现可以使用双引号括住
    f = "I' love Tom"
    print(f)
    
    ============================================================================
    
    # 字符串的输出 
    
    name = 'Tom'
    print('我的名字是%s' % name)
    print(f'我的名字是{name}')
    
    ==============================================================================
    
    # 字符串的输入
    password = input('请输入您的密码')
    print(f'您输入的密码是{password}')
    # input接收到的用户输入的数据都是字符串
    print(type(password))
    
    

    4.2 下标和切片

    (1)下标

    str1 = 'abcdefg'
    print(str1)
    # 数据在运行过程中存储在内存
    # 使用字符串中特定的数据
    # 使用编号精确找到某个字符数据,下标索引值
    # str[下标]
    print(str1[0])  # 输出a
    print(str1[1])  # 输出b
    
    

    (2)切片

    # 序列名[开始位置的下标:结束位置的下表:步长]
    # 取值区间左闭右开的
    
    str1 = '012345678'
    # print(str1[2:5:1]) 234
    # print(str1[2:5:2]) 24
    # print(str1[2:5]) 234  # 如果不写步长,默认步长是1
    # print(str1[:5]) 01234   # 如果不写开始,默认从0开始选取
    # print(str1[2:]) 2345678 # 如果不写结束,表示选取到最后
    # print(str1[:]) 012345678  # 如果不写开始和结束,表示选取所有
    
    # 负数测试
    # print(str1[::-1]) 876543210 # 如果步长为负数,表示倒叙选取
    # print(str1[-4:-1])  567    下标为-1表示最后一个数据,依次向前类推
    
    # 终极测试
    # print(str1[-4:-1:1]) 567
    print(str1[-4:-1:-1]) # 不能选取出数据:从-4开始到-1结束,选取方向从左到右,但是-1步长:从右向左选取
    # 如果选取方向(下标开始到结束的方向)和步长方向冲突,则无法选取数据
    print(str1[-1:-4:-1]) # 876 方向一致就可以正确输出
    
    

    小总结: 下标是精确的找到某一个元素,切片可以利用下标找到某一部分元素(左闭右开)

    4.3 字符串常用操作方法(查找、修改、判断)

    (1)查找

    mystr = 'hello world and itcast and itsmail and Python'
    
    # 1. find()
    print(mystr.find('and')) # 输出的是12,以为下标是从0开始数的
    print(mystr.fing('and',15,30))
    print(mystr.find('ands')) # -1,ands字串不存在
    
    # 2. index
    print(mystr.find('and')) # 12
    print(mystr.find('and',15,30)) #23
    print(mystr.index('ands')) #如果index查找字串不存在,报错
    
    # 3. count()
    print(mystr.count('and')) 3
    print(mystr.count('and',15,30)) 1
    print(mystr.count('ands')) 0
    
    # 4. rfind()
    print(mystr.rfind('and')) 35
    print(mystr.find('ands')) -1 如果没找到,则返回-1
    
    # 5. rindex()
    print(mystr.rindex('and')) 35  就算是到着找,它的下标还是从左到右从下标0开始的
    print(mystr.rindex('ands'))
    
    

    (2)修改

    # 遇到列表、字典,内部的数据可以直接修改,修改的就是原列表或者原字典。叫做可变类型。
    # 字符串是一个不可变类型的数据
    
    mystr = 'hello world and itcast and itheima and Python'
    # replace() 把and换成he replace函数有返回值,返回值是修改后的字符串
    new_str = mystr.replace('and','he')
    # new_str = mystr.replace('and','he',1)
    # 替换次数如果超出字串出席那的次数,表示替换所有这个字串
    # new_str = mystr.replace('and','he',10)
    print(mystr)
    print(new_str)
    
    # 调用了replace函数后,发现原有字符串的数据并没有做到修改,修改后的数据是replace函数的返回值
    # 说明字符串是不可变数据类型
    # 数据是否可以改变划分为 可变类型,不可变类型
    
    # 2. split()  分割,返回一个列表,丢失分割字符
    list1 = mystr.split('and')
    print(list1)
    
    # 3. join() 合并列表里面的字符串数据为一个大字符串
    mylist = ['aa','bb','cc']
    new_str = '...'.join(mylist)
    print(new_str)
    

    修改-非重点

    # 一、字符串对齐
    # mystr.ljust(10) 左对齐
    # mystr.rjust(10) 右对齐
    # mystr.rjust(10,'.') 以点作为填充效果
    # mystr.center(10) 中间居中
    # mystr.center(10,'.') 以点填充空白的地方
    
    
    
    # 二、大小写转换
    mystr = 'hello world and itcast and itheima and Python'
    # 1. capitalize() 字符串首字母大写
    # new_str = mystr.capitalize()
    # print(new_str)
    
    # 2. title():字符串中每个单词首字母大写
    # new_str = mystr.title()
    # print(new_str)
    
    # 3. upper():小写转大写
    # new_str = mystr.upper()
    # print(new_str)
    
    # 4. lower():大写转小写
    # new_str = mystr.lower()
    # print(new_str)
    
    
    # 三、删除空白字符
    str1 = "      hello world and itcast and itheima and Python  "
    # 1. lstrip():删除字符串左侧空白字符
    # print(str1)
    # new_str = str1.lstrip()
    # print(new_str)
    
    # 2. rstrip():删除字符串右侧空白字符
    new_str = str1.rstrip()
    print(str1)
    print(new_str)
    
    # 3. strip():删除字符串两侧空白字符
    # new_str = str1.strip()
    # print(new_str)
    
    

    (3)判断

    # 判断开头或结尾
    mystr = 'hello world and itcast and itheima and Python'
    # 1. startswith(字串,开始位置下标,结束位置下标):判断字符串是否以某个字串开头
    print(mystr.startswith('hello'))
    print(mystr.startswith('hel'))
    print(mystr.startswith('hels'))
    print(mystr.startswith('hell',0,10)) 开始位置下标和结束位置下标可以省略
    
    # 2. endswich(字串,开始位置下标,结束位置下标),始位置下标和结束位置下标可以省略
    print(mystr.endswith('Python'))
    print(mystr.endswith('Pythons'))
    
    # 判断
    3. isalpha():字母  纯字母才可以,如果中间有空格返回的false
    print(mystr.isalpha())
    
    # 4. isdigit():数字,中间也不能有空格,否则返回false
    print(mystr.isdigit())
    mystr1 = "12345"
    print(mystr1.isdigit())
    
    # 5. isalnum():数字或字母或组合
    print(mystr1.isalnum()) # True
    print(mystr.isalnum())  # False 因为中间有空格
    mystr2 = 'abc123'
    print(mystr2.isalnum())
    
    # 6. isspace():判断是否是空白,是返回True
    print(mystr.isspace())  # False
    mystr3 = ' '
    print(mystr3.isspace())	 # True
    

    5. 列表、元组和字典

    5.1 列表的创建和使用

    name_list = ['TOM','Lily','ROSE']
    print(name_list)   # ['TOM', 'Lily', 'ROSE']
    # 根据下标进行输出
    print(name_list[0])  # 输出 TOM
    print(name_list[1])  # 输出 Lily
    print(name_list[2])  # 输出 ROSE
    
    

    5.2 判断数据是否在列表中存在

    name_list = ['TOM','Lily','ROSE']
    # 1. in  如果在里面就返回true,否则false
    print('TOM' in name_list)
    print('TOMS' in name_list)
    
    # 2. not in   这个跟in相反
    print('TOM' not in name_list)
    print('TOMS' not in name_list)
    
    

    体验案例

    name_list = ['TOM','List','ROSE']
    
    # 需求:注册邮箱,用户输入一个账户名,判断这个账号是否存在,如果存在,提示用户,否则提示可以注册
    name = input("请输入您的邮箱账号名:")
    if name in name_list:
        # 提示用户名已经存在
        print(f'您输入的名字是{name},此用户已经存在')
    else:
        # 提示可以注册
        print(f'您输入的名字是{name},可以注册')
    

    5.3 列表的常见操作(查找、增加、删除、修改、赋值)

    (1)查找(index、count、len)

    name_list = ['TOM','Lily','Rose']
    
    # 1.index()
    print(name_list.index('TOM'))  #返回 0
    # print(name_list.index('TOMs'))  没有找到,报错
    
    # 2. count()
    print(name_list.count('TOM'))
    # print(name_list.count('TOMS')) # 报错
    
    # 3.len()
    print(len(name_list)) # 输出3
    

    (2)增加(append、extend、insert)

    # 1. 列表数据是可变的  -- 列表是可变类型
    # 2. append函数追加数据的时候如果是一个序列,追加整个序列到列表的结尾
    
    name_list = ['TOM','Lily','ROSE']
    name_list.append('xiaoming')
    name_list.append([11,22])
    name_list.append(11)
    print(name_list)  # 输出结果为:['TOM', 'Lily', 'ROSE', 'xiaoming', [11, 22], 11]
    
    # extent() 追加数据是一个序列,把数据序列里面的数据拆开然后逐一追加到列表的结尾
    name_list = ['TOM','Lily','ROSE']
    name_list.extend('xiaoming')
    # 把序列拆开,逐一的放到列表中
    name_list.extend(['xiaoming','xiaojun'])
    print(name_list) 
     # 输出结果为:['TOM', 'Lily', 'ROSE', 'x', 'i', 'a', 'o', 'm', 'i', 'n', 'g', 'xiaoming', 'xiaojun']
    
    
    name_list = ['Tom','Lily','ROSE']
    # name_list.insert(下标,数据)  在指定位置加入数据
    name_list.insert(1,'aa')
    print(name_list) # 输出的结果为:['Tom', 'aa', 'Lily', 'ROSE']
    
    

    (3)删除(del、pop、remove、clear)

    name_list = ['Tom','Lily','ROSE']
    
    # 1. del
    # del name_list
    # print(name_list) 已经把列表已经删除,已经没有列表了
    
    # del 也可以指定下标的数据
    # del name_list[0]
    # print(name_list)   # 输出的结果 ['Lily', 'ROSE']
    
    
    # 2. pop() 删除指定下标的数据,如果不指定下标,默认删除最后一个数据
    # 无论是按照下标还是删除最后一个,pop函数都会返回这个被删除的数据. 比较厉害的是删除一个数据能用一个变量去接收
    del_name = name_list.pop()
    del_name = name_list.pop(1)
    print(del_name)
    print(name_list)
    
    # 3. remove(数据) 按照指定的数据进行删除的
    # name_list.remove('ROSE')
    # print(name_list)
    
    # 4. clear() -- 清空
    # name_list.clear()
    # print(name_list)  # 直接清空整个数据
    
    

    (4)修改(reverse、sort)

    name_list = ['TOM','Lily','ROSE']
    
    # 修改指定下标的数据
    # name_list[0] = 'aaa'
    # print(name_list) # ['aaa', 'Lily', 'ROSE']
    
    # 2. 逆序 reverse()
    list1 = [1, 3, 4, 2, 5]
    # list1.reverse()
    # print(list1)
    
    # 3. sort() 排序:升序(默认)和 降序
    # list1.sort()  # 升序
    list1.sort(reverse=False)  # 升序 [1, 2, 3, 4, 5]
    list1.sort(reverse=True)   # 降序 [5, 4, 3, 2, 1]
    print(list1)
    
    

    (5)赋值

    name_list = ['tom','lucy','jack']
    list1 = name_list.copy()
    print(list1)
    print(name_list)
    
    

    5.4 列表的循环遍历(for、while)

    for循环

    name_list = ['tom','rose','jack']
    i = 0
    while i < len(name_list):
        print(name_list[i])
        i += 1
    

    while循环

    # for循环的代码量要少于while的代码量
    # 一般在工作岗位下,涉及到遍历序列当中的数据的话,一般优选于for循环
    name_list = ['tom','rose','jack']
    for i in name_list:
        # 遍历序列中的数据
        print(i)
        
    

    5.5 列表的嵌套

    列表嵌套时的数据查询

    name_list = [['TOM', 'Lily','Rose'], ['张三','李四','王二'], [ '小红', '小绿', '小蓝']]
    # print(name_list)
    # 列表嵌套的时候的数据查询
    print(name_list[0])
    print(name_list[0][0])
    
    

    案例-随机分配办公室

    # 需求:八位老师,3个办公室,将8为老师随机分配到3个办公室
    '''
    步骤::
    1.准备数据
        1.1 8位老师 -- 列表
        1.2 3个办公室 -- 列表嵌套
    2. 分配老师到办公室
        随机分配
        就是把老师的名字写入到办公室列表 --办公室列表追加老师数据
    3. 验证是否分配成功
        打印办公室详细信息: 每个办公室的人数和对应的老师名字
    
    '''
    import random # 随机模块
    # 1. 准备数据
    teachers = ['A','B','C','D','E','F','G','H']  # 列表存数据
    offices = [[], [], []]      # 嵌套列表
    
    # 2. 分配老师到办公室 -- 取到每个老师放到办公室列表 -- 遍历老师列表数据
    for name in teachers:
        # 列表追加数据  -- append(整体添加) --extend(拆开添加) --insert(在指定位置加入数据)
        num = random.randint(0,2)
        offices[num].append(name)           #追加数据
    # print(num)
    # print(offices)
    
    # 为了更贴合生活,把各个办公室子列表加一个办公室编号1 ,2 ,3
    i = 1
    # 3. 验证是否成功
    for office in offices:
        # 打印办公室人数 -- 子列表数据的个数 len()
        print(f'办公室{i}的人数是{len(office)}')
        # 打印老师的名字
        # print() -- 每个自立表里面的名字个数不一定 -- 遍历 -- 子列表
        for name in office:
            print(name)
        i += 1
    

    5.6 元组的访问

    注意: 如果是单个数据的元组,那么后面必须加逗号,否则就不是元组的数据类型,而是整个数据本身的数据类型

    # 输出元组
    t1 = (10, 20, 30)
    print(t1)  # 输出 (10, 20, 30)
    
    # 如果是单个数据的元组,那么后面必须加逗号,否则就不是元组的数据类型,而是整个数据本身的数据类型
    # 1.多个数据元组
    t1 = (10, 20, 30)
    print(type(t1))  # 输出 <class 'tuple'>
    
    # 2. 单个数据元组
    t2 = (10,)
    print(type(t2))  # 输出 <class 'tuple'>
    =====================================================================
    
    # 3. 如果单个数据的元组不加逗号
    t3 = (10)
    print(type(t3))  # 输出 <class 'int'>
    
    t4 = ('aaa')
    print(type(t4))  # 输出 <class 'str'>
    ================================================================================
    t5 = ('aaa',)
    print(type(t5))  # 输出  <class 'tuple'>
    

    5.7 元组常见操作(查找、修改)

    (1)查找

    t1 = ('aa', 'bb', 'cc')
    
    # 1. 下标
    print(t1[0])   # aa
    
    # 2. index()
    print(t1.index('aa'))  # 输出0  其实有参数二,有参数三对应一个查找的范围,如果没有找到就直接报错。
    
    # 3. count()
    print(t1.count('aa')) # 统计aa的次数,输出结果为1
    
    # 4. len()
    print(len(t1))  # 统计整个元组的个数,输出结果为3
    

    (2)修改

    # 元组确实不能修改,但是元组中含有的列表可以修改。
    # 工作中尽可能遵循一个规则,但凡是出现在小括号元组里面的数据,尽可以能靠自觉去要求不做修改
    # 工作中如果是同事的代码,有数据出现在元组中,尽可能在查找操作的时候,小心一点,尽可能不要去修改这一部分的操作。
    
    t1 = ('aa', 'bb', 'cc')
    # t1[0] = 'aaa' 这个操作是错的,是不能修改的。
    t2 = ('aa', 'bb', ['cc', 'dd'])
    print(t2[2])
    t2[2][0] = 'TOM'
    print(t2)
    
    展开全文
  • 1、为什么学习Python? 人生苦短?人间不值得?想想自己的初心吧! 2、通过什么途径学习的Python? 官网、网上视频、学习网站、论坛、大牛的辅导 3、Python和Java、PHP、C、C#、C++等其他语言的对比? (1)、python...
  • 编程:Python基础笔试题(附答案)

    万次阅读 2019-05-09 11:01:47
    1.下列哪个语句在Python中是非法的? A、x = y = z =1 B、x = (y = z + 1) C、x, y = y, x D、x += y 答案:B 2.关于Python内存管理,下列说法错误的是 A、变量不必事先声明 B、变量无须先创建和赋值而直接使用 C...
  • python基础代码汇总

    万次阅读 2019-05-10 12:08:27
    期末汇总
  • python基础知识点总结

    千次阅读 2019-03-17 20:36:49
    Python简介 1.计算机 1.1 计算机概念 计算机【computer】俗称电脑,是现代一种用于高速计算的电子机器。 1.2 计算机组成 计算机由硬件系统与软件系统组成。 计算机硬件系统包含: 运算器:用于进行计算的...
  • python基础知识刷题

    千次阅读 2018-07-25 10:37:27
    1,执行Python脚本的两种方式 1 2 3 4 五 交互方式:命令行   Windows操作系统下,快捷键cmd,输入“python”启动交互式python解释器。   文件方式:python文件 ...
  • Python基础教程(一)

    万次阅读 多人点赞 2019-04-23 00:42:29
    Python基础教程 一、简介 Python的历史和为什么学习Python这里就不在赘述了。处于工作原因,对Python要进行深入的学习和研究,这里主要针对的就是Python具有的丰富和强大的库。 Python目前有两个版本,Python2和...
  • python基础语法总结

    万次阅读 多人点赞 2018-04-27 14:36:42
    本文参考廖雪峰的python教程输入和输出输出用print()在括号中加上字符串,就可以向屏幕上输出指定的文字。比如输出'hello, world',用代码实现如下:&gt;&gt;&gt; print('hello, world') print()函数也...
  • Python 基础(一):入门必备知识

    万次阅读 多人点赞 2020-09-22 19:56:09
    Python 入门必备知识,你都掌握了吗?
  • python 入门基础和数据类型测试题 1. 在Python语言中,不能作为变量名的是( ) A. P B. Temp C. 3p. D. _fg 2.以下关于Python缩进的描述中,错误的是( ) A. Python用严格的缩进表示程序的格式框架,所有代码都...
  • Python 基础教程

    万次阅读 多人点赞 2015-07-01 11:17:18
    Python 基础教程 Python 基础教程 Python 简介 Python 环境搭建 Python 中文编码 Python 基础语法 Python 变量类型 Python 运算符 Python 条件语句 Python 循环语句 Python While循环语句 Python for ...
  • Python基础教程系列目录,最全的Python入门教程

    千次阅读 多人点赞 2017-07-06 10:07:23
    在现在的工作及开发当中,Python的使用越来越广泛,为了方便大家的学习,Linux大学 特推出了 《Python基础教程系列》。 本系列教程适合Python小白阅读,是Python入门的必备教程! 本系列教程共包含如下文章: ...
  • python基础教程 python基础系列教程——Python的安装与测试:python解释器、PyDev编辑器、pycharm编译器 python基础系列教程——Python库的安装与卸载 python基础系列教程——Python3.x标准模块库目录 ...
  • Python基础知识归纳

    千次阅读 多人点赞 2019-05-18 10:38:18
    Python 基础教程 Python 基础教程 Python 简介 Python 环境搭建 Python 中文编码 Python 基础语法 Python 变量类型 Python 运算符 Python 条件语句 Python 循环语句 Python While 循环语句 Python for ...
  • 小甲鱼零基础入门学习Python(绝对干货,值得学习) 链接: https://pan.baidu.com/s/1jJmIrlk 密码: ktp2
  • Python3零基础入门学习视频+源码+课件+习题

    万次阅读 多人点赞 2020-05-15 09:21:28
    本文已迁移至:https://www.cnblogs.com/coco56/p/11925047.html
1 2 3 4 5 ... 20
收藏数 540,181
精华内容 216,072
关键字:

python基础