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基础知识点梳理

    2020-02-04 20:23:57
    本文主要介绍一些平时经常会用到的python基础知识点,用于加深印象。python的详细语法介绍可以查看官方编程手册,也有一些在线网站对python语法进行了比较全面的介绍,比如菜鸟教程: python3 教程|菜鸟教程 本文...

    python基础知识点梳理

    摘要:
    本文主要介绍一些平时经常会用到的python基础知识点,用于加深印象,也算是对于学习这门语言的一个总结与回顾。python的详细语法介绍可以查看官方编程手册,也有一些在线网站对python语法进行了比较全面的介绍,比如菜鸟教程:
    python3 教程|菜鸟教程
    为了方便聚焦知识点,本文涉及的操作实例并不多,想学好一门语言关键还得自己多编码多实践。

    python语言介绍

    python是一门解释型语言,python的设计目标:

    • 一门简单直观的语言并与主要竞争者一样强大
    • 开源,以便任何人都可以为它做贡献
    • 代码像纯英语那样容易理解
    • 适用于短期开发的日常任务

    设计哲学是:

    1. 优雅
    2. 明确
    3. 简单

    python基础语法

    标识符

    • 第一个字符必须是字母表中字母或下划线 。
    • 标识符的其他的部分由字母、数字和下划线组成。
    • 标识符对大小写敏感。

    注释

    类型 语法
    单行注释 以 # 开头,编程规范建议#后面跟一个空格
    多行注释 用一对连续的三个引号,单引号或者双引号均可("""/’’’)

    行与缩进

    • python与其他语言明显的区别是没有大括号,而是用缩进表示代码块。
    • 另外,每行语句不需要以分号结束。

    多行语句

    如果语句很长,可以使用反斜杠(\)来实现多行语句
    说明:在 [], {}, 或 () 中的多行语句不需要使用反斜杠

    算术运算符

    运算符 描述 实例
    + 两个对象相加 10 + 9 = 19
    - 两个对象相减 10 - 9 = 1
    * 两个数相乘法,用于字符串时可以重复多次 10 * 9 = 90
    / x除以y 10 / 2 = 5
    // 取整除 10 // 9 = 1
    % 取余数 10 % 8 = 2
    ** 返回x的y次幂 10 ** 2= 100

    判断语法

    if else语句

    if 和 else用于对条件进行判断并进行处理,语法如下:

    if 要判断的条件:
    	条件成立时要做的事情
    	...
    else:
    	条件不成立时要做的事情
    
    逻辑运算符

    对于同时判断多个条件的情况可以用逻辑运算符,有如下三种:

    符号 说明 语法
    and ,两个都成立才返回True 条件1 and 条件2
    or ,两个只要有一个满足就返回True 条件1 or 条件2
    not ,对条件取反 not 条件
    elif 语句

    elif语句用于有多个条件进行判断的场景,语法如下:

    if 条件1:
    	条件1满足时执行的代码
    elif 条件2:
    	条件2满足时执行的代码
    elif 条件3:
    	条件3满足时执行的代码
    else:
    	以上都不满足时执行的代码
    

    循环语法

    循环的作用就是让指定的代码重复执行

    while循环

    while循环是python中常见的循环,用于让执行的代码按照指定次数重复执行,语法如下:

    初始条件设置,通常是计数器
    while 条件(判断计数器是否达到目标次数):
    	条件满足时候执行的代码
    	...
    	处理条件(计数器 + 1)
    
    for循环

    for循环可以方便地遍历列表,元组,字典等数据类型,比如遍历一个列表的代码片段如下:

    nameList = ["zhangsan", "lisi", "wangwu"]
    for name in nameList:
    	print(name)
    

    python中,for循环经常与range函数搭配使用,如下:

    for i in range(1, 10):
    	print(i)
    

    python数据类型介绍

    • 按照是否是数字可以按照如下表格分类:
    数字类型 非数字类型
    整型(int)/ 浮点型(float)/ 布尔型(bool)/ 复数型(complex) 字符串(str)/ 列表(list)/ 元组(tuple) / 字典(dict)

    说明:使用type函数可以返回变量的数据类型

    按照是否可变可以分为:

    不可变类型 可变类型
    整型(int)/ 浮点型(float)/ 布尔型(bool)/ 复数型(complex)/ 字符串(str)/ 元组(tuple) 列表(list)/ 字典(dict)

    列表

    列表(list)是python中使用最频繁的数据类型,类似其他语言的数组
    列表的符号是中括号[],初始化一个列表语法如下:

    program_list = ["c++", "java", "python", "php"]
    

    列表中常见的几种操作如下:

    序号 分类 方法 说明 实例
    01 查询 list.index(obj) 从列表中找出某个值第一个匹配项的索引位置 program_list.index(“java”))
    02 增加 list.insert(index, obj) 在列表中指定位置插入数据 program_list.insert(1, “kotlin”)
    03 增加 list.append(obj) 在列表末尾追加数据 program_list.append(“C#”)
    04 增加 list.extend(list1) 在列表1的数据追加到列表中 program_list.extend([“C#”, “kotlin”, “bash”])
    05 增加 list.extend(list1) 在列表1的数据追加到列表中 program_list.extend([“C#”, “kotlin”, “bash”])
    06 修改 list[index] = obj 修改指定索引的数据 program_list[2] = “Go”
    07 删除 list.clear() 清空列表 program_list.clear()
    08 删除 list.remove(obj) 删除第一个出现的指定数据 program_list.remove(“java”)
    09 删除 list.pop() 删除末尾的数据 program_list.pop()
    10 删除 list.pop(index) 删除指定索引的数据 program_list.pop(1)
    11 统计 len(list) 计算列表长度 len(program_list)
    12 统计 list.count(obj) 统计数据在列表中出现的次数 program_list.count(“java”)
    13 排序 list.sort() 将列表升序排列 program_list.sort()
    14 排序 list.sort(reverse=True) 将列表降序排列 program_list.sort(reverse = True)
    15 翻转 list.reverse() 将列表翻转 program_list.reverse()

    元组

    元组(tuple)与列表类似,区别是元组的数据不能修改,元组的符号是小括号(),初始化一个元组的语法如下:

    program_tuple = ("c++", "java", "python", "php")
    

    元组主要用于函数的参数和返回值,格式化字符串,以及保护列表数据,由于元组的数据无法修改,因此提供的方法也比较少:

    序号 分类 方法 说明 实例
    01 查询 tuple.index(obj) 从元组中找出某个值第一个匹配项的索引位置 program_tuple.index(“java”)
    02 统计 len(tuple) 计算元组长度 len(program_tuple)
    03 统计 tuple.count(obj) 统计数据在列表中出现的次数 program_tuple.count(“python”)

    元组在python中还可以用于交换两个变量的值:

    a = 10
    b = 9
    a, b = (b, a)
    

    字典

    字典(dict)通常用于描述一个物体的相关信息,使用键值对存储数据,键必须唯一,由于要使用hash算法,只有不可变类型才能用作键,字典的符号是大括号{},初始化一个字典的语法如下:

    human_dic = {"name": "zhangsan",
    			"age": 26,
    			"height": 1.75,
    			"weight": 66}
    

    字典的常用操作函数如下:

    序号 分类 方法 说明 实例
    01 取值 dict[key] 从字典中取出键对应的值 human_dic[“name”]
    02 取值 dict.get(key) 从字典中取出键对应的值 human_dic.get(“name”)
    03 取值 dict.items() 以列表返回可遍历的(键, 值) 元组数组 list(human_dic.items())
    04 取值 dict.keys() 以列表返回一个字典所有的键 list(human_dic.keys())
    05 取值 dict.values() 以列表返回字典中的所有值 list(human_dic.values())
    06 增加/修改 dict[key] = value key存在则更新value,否则增加键值对 human_dic[“gender”] = “male”
    07 删除 dict.pop(key) pop函数返回key对应的value值,并删除键值对 human_dic.pop(“gender”)
    08 删除 dict.popitem() 返回并删除字典中的最后一对键和值 human_dic.popitem()
    09 合并 dict.update(dic2) 合并字典dic2中的数据,已存在的key跟新value的值 human_dic.update({“weight”: 64, “age”: 27})
    10 复制 dict.copy() 返回字典的浅复制 new_dic = human_dic.copy()
    11 清空 dict.clear() 清空字典 human_dic.clear()

    字符串

    字符串(str)的使用也非常广泛,可以使用引号('或")来创建字符串,初始化一个字符串的语法如下:

    testStr = "Wasting time is robbing oneself"
    

    python对于str提供了很多实用的方法,比较常用的有以下这些:

    • 对字符串进行判断的方法:
    序号 方法 说明
    01 str.isalnum() 如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False
    02 str.isalpha() 如果 string 至少有一个字符并且所有字符都是字母则返回 True,否则返回 False
    03 str.isdecimal() 如果 string 只包含数字则返回True,否则返回False
    04 str.istitle() 如果 string 是标题化的(每个单词的首字母大写)则返回True
    05 str.isupper() 如果 string 所有区分大小写的字符都是大写,则返回True
    06 str.islower() 如果 string 所有区分大小写的字符都是小写,则返回True
    07 str.isspace() 如果 string 中只包含空格,则返回 True,否则返回 False
    • 对字符串进行修改(包括格式化,大小写转换):
    序号 分类 方法 说明
    01 格式化 str.format() 格式化字符串
    02 格式化 str.strip() 去掉字符串左右两边的空白字符
    03 格式化 str.lstrip() 去掉字符串左边的空白字符
    04 格式化 str.rstrip() 去掉字符串右边的空白字符
    05 文本对齐 str.ljust(width) 返回一个原字符串左对齐,并使用空格填充宽度至长度width的新字符串
    06 文本对齐 str.rjust(width) 返回一个原字符串右对齐,并使用空格填充宽度至长度width的新字符串
    07 文本对齐 str.center(width) 返回一个原字符居中对齐,并使用空格填充宽度至长度width的新字符串
    08 大小写 str.title() 把字符串的每个单词首字母大写
    09 大小写 str.lower() 把字符串的所有大写字符转换成小写
    10 大小写 str.upper() 把字符串的所有小写字符转换成大写
    11 大小写 str.swapcase() 翻转字符串的大小写
    • 字符串的查找和替换:
    序号 方法 说明
    01 str.count(str1, beg=0, end=len(string)) 返回 str1 在字符串中出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数
    02 str.startswith(obj, beg=0,end=len(string)) 检查字符串是否是以 obj 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查.
    03 str.endswith(obj, beg=0, end=len(string)) 检查字符串是否以 obj 结束,是则返回 True,否则返回 False。如果beg 或者 end 指定值,则在指定范围内检查
    04 str.find(str1, beg=0, end=len(string)) 检测 str1是否包含在字符串中,如果 beg 和 end 指定范围,则检查是否包含在指定范围内。如果是则返回开始的索引值,否则返回-1
    05 str.rfind(str1, beg=0,end=len(string) ) 类似于find函数,不过是从右边开始查找
    06 str.index(str1, beg=0, end=len(string)) 跟find()方法一样,只不过如果str1不在 字符串中会报一个异常.
    07 str.rindex(str1, beg=0, end=len(string)) 类似于index函数,不过是从右边开始
    08 str.replace(str1, str2, num=string.count(str1)) 把 字符串中的 str1 替换成 str2,如果 num 指定,则替换不超过 num 次.
    • 字符串的拆分和连接:
    序号 方法 说明
    01 str.split(str1="", num=str.count(str1)) 以 str1 为分隔符切片字符串,如果 num 有指定值,则仅分隔 num+1 个子字符串
    02 str.splitlines([keepends]) 按照行(’\r’, ‘\r\n’, \n’)分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。
    03 str.join(seq) 以 字符串作为分隔符,将 列表seq 中所有的元素(用字符串表示)合并为一个新的字符串

    公共方法

    内置函数

    对于列表,元组,字典,字符串,python也提供了一些公共方法,如下:

    函数 描述 说明
    len(item) 计算元素的总个数
    del(item) 删除变量 可以删除整个变量,加上索引可以只删除指定的元素
    max(item) 返回元素的最大值 字典只针对key比较
    min(item) 返回元素的最小值 字典只针对key比较
    运算符

    高级数据类型同样支持以下常见的运算符:

    序号 运算符 描述 支持的数据类型
    01 + 合并 列表,元组,字符串
    02 * 重复 列表,元组,字符串
    03 in 元素是否存在 列表,元组,字典,字符串
    04 not in 元素是否不存在 列表,元组,字典,字符串
    05 > < >= <= == 比较 列表,元组,字符串
    切片

    切片使用索引值可以方便地截取容器中一定范围的数据,适用于列表,元组,字符串。
    切片语法如下:
    item[N:M:S]
    其中N表示要截取的开始位置,M表示结束位置,S表示step也就是步长,默认是1,截取的时候[N:M]是个半闭合区间,等效于数学上[N,M)取值范围,取N不取M, N和M都可以省略。python中,-1可以表示最后一个元素,字符串利用切片完成翻转的代码如下:

    >>> test_str = "Hello World"
    >>> print(test_str[::-1])
    

    python函数语法

    在python中定义一个函数需要使用def关键字,相比其他语言,返回值不需要声明,定义一个函数的语法如下:

    def print_hello():
    	print("Hello, World!")
    

    缺省参数

    除了常见的必须参数外,python支持缺省参数,即为参数指定一个默认值,可以不传入这个参数,代码例子如下:

    def print_human(name, age = 23):
    	print("body info: name is %s, age is %s" % (name, age) )
    	
    print_human("wangwu")
    print_human("lisi", 25)
    print_human("zhangsan", age = 36)
    

    多值参数

    如果函数处理的参数的个数不确定,就可以用多值参数:

    1. 参数名前面增加一个*可以接收元组
    2. 参数名前面增加两个*可以接收字典

    使用了这两个多值参数的代码例子如下:

    def print_info(*args, **kwargs):
    	print(args)
    	print(kwargs)
    	
    program_list = ["c++", "java", "python", "php"]
    human_dic = {"name": "zhangsan", "age": 26, "height": 1.75, "weight": 66}
    	
    print_info(*program_list, **human_dic)
    

    返回多个值

    python中可以利用元组返回多个值,多个返回值的代码如下:

    def measure_rect():
    	width = 12
    	height = 6
    	return width, height
    
    w, h = measure_rect()
    print("width is %d, height is %d" % (w, h))
    

    python常用函数

    print输出函数

    python使用print函数将信息输出到控制台,输出数据时经常会用到格式化操作符,不同的格式化字符串含义如下表:

    格式化字符 含义
    %s 字符串
    %d 有符号十进制整数(%07d 表示显示7位整数,不足就用0补全)
    %f 浮点数(%.02f 表示小数点后显示两位)
    %% 输出%

    语法格式如下:

    print("格式化字符串" % 变量1)
    print("格式化字符串" % (变量1, 变量2...))
    

    print函数默认会自动在内容末尾增加换行,如果不希望换行,可以用end参数指定需要输出的内容
    语法格式如下:

    print("Hello word!", end="")
    

    input输入函数

    使用input函数从键盘等待用户的输入,默认都是一个字符串
    语法格式如下:

    字符串变量 = input("提示信息:")
    

    类型转换函数

    常见的类型转换函数如下:

    函数 说明
    int(x) 将x转换为一个整数
    float(x) 将x转换为一个浮点数
    str(list) 将列表转换为字符串
    tuple(list) 将列表转换为元组
    list(tuple) 将元组转换为列表
    展开全文
  • Python基础知识及概念

    2018-05-24 23:23:05
    第四天 Python基础知识及概念1. 注释单行注释#这是一个单行注释 · 在程序开发时,同样可以使用 # 在代码的后面(旁边)增加说明性的文字· 但是,需要注意的是,为了保证代码的可读性,注释和代码之间 至少...

                                        Python基础知识及概念

    1.     注释

    单行注释

    #这是一个单行注释 

    ·       在程序开发时,同样可以使用 # 在代码的后面(旁边)增加说明性的文字

    ·       但是,需要注意的是,为了保证代码的可读性注释和代码之间 至少要有 两个空格

    ·       示例代码如下:

    print("hello python")  # 输出 `hello python`

    多行注释

    可以选中要注释的行 同时按下 Ctrl+/ 可以实现多行注释与取消注释

     

    也可以用三对引号来注释 如下:

    """
    这是一个多行注释
     
    在多行注释之间,可以写很多很多的内容……
    """ 
    print("hello python")

    注意:注释不是越多越好,一目了然的程序不需要注释,对于复杂的操作可以写上若干注释。

    任何语言的编程员,编写出符合规范的代码,是开始程序生涯的第一步!

     

    2.     算术运算符

    算术运算符不在此多说,只要记住一点:除法的返回结果永远都是浮点数float

     

    3.     Python执行程序的执行原理

    1.      操作系统会首先让CPU把Python解释器的程序复制到内存中

    2.      Python解释器根据语法规则,从上到下让CPU翻译Python程序中的代码

    3.      Cpu负责执行翻译完成的代码

    程序是用来处理数据的 而变量是用来存储数据的

     

    4.      变量的类型

      数字型   整型  浮点型 布尔型 复数型

      非数字型  字符串  列表  元组  字典

    数字型变量之间可以直接计算:

    2*True=2

    3.3*False=0

     

     

    5.字符串变量的运算

    1.      first_name=”三”

    last_name=”张”

    first_name+last_name=”三张”

    +号实现字符串之间的拼接

    2.      字符串与整型相乘

    First_name=”张三”

    First_name*3=“张三张三张三”

       3.字符串和数字型变量不能进行其他运算

       

    6.变量的格式化输出

    例如:输入苹果的单价,输入买苹果的重量,计算出总共的价格

    原始算法:


     

     

    改进算法:

     

    格式化输出算法:

     

    终极算法(一行搞定)

    print("请付{:}元钱".format(float(input("苹果的单价是:")) * float(input("苹果的重量是:"))))

     

    思考:

    在控制台依次提示用户输入:姓名、公司、职位、电话、邮箱

                       按照以下格式输出(提示:* 号是50个):

                       **************************************************

                       公司名称:

                       姓名:

                       职位:

                       电话:

                       邮箱:

                       **************************************************

    print("{:}\n公司名称:{:}\n姓名:{:}\n职位:{:}\n电话:{:}\n邮箱:{:}\
    \n
    {:}"
    .format("*"*50,input("公司名称:"),input("姓名:"),input("职位:"),input("电话:"),input("邮箱:"),"*"*50))

     

     

    提示用户输入一个大于100 小于999 的数字,然后打印个位,十位,百位。

                                 提示:用求余符号 % 和求整符号//

                       如:

                       请输入一个数字:356

                       您输入的数字为:356

                       百位:3 ,十位:5 ,个数:6

    num=eval(input("请输入一个大于100且小于999的数字:"))
    print("百位:{:.0f}\n十位:{:.0f}\n个位:{:.0f}".format(num//100,num%100//10,num%10//1))

    7.变量的命名

    标示符就是程序员定义的 变量名、函数名

    名字 需要有 见名知义 的效果:

    标示符可以由 字母、下划线 和 数字 组成

    不能以数字开头 不能与关键字重名

    标识符的命名是区分大小写的

     

    1.小驼峰式命名法

    第一个单词以小写字母开始,后续单词的首字母大写

    例如:firstName、lastName

    2.大驼峰式命名法

    每一个单词的首字母都采用大写字母

    例如:FirstName、LastName、CamelCase

    展开全文
  • Python基础知识点总结

    2017-03-23 15:04:03
    Python基础知识

       学了一年多的Python,去年做了一段时间的爬虫项目,近来在做数据分析和机器学习的东西,抽空整理一下以前学的Python基础知识点,有借鉴与总结。具体知识点后续会分段展开深入。

       

    1.到底什么是Python?你可以在回答中与其他技术进行对比(据说是某面试题)。

    答案:下面是一些关键点:

    l Python是一种解释型语言。这就是说,与C语言和C的衍生语言不同,Python代码在运行之前不需要编译。其他解释型语言还包括PHP和Ruby。

    l Python是动态类型语言,指的是你在声明变量时,不需要说明变量的类型。你可以直接编写类似x=111和x="I'm a string"这样的代码,程序不会报错。

    l Python非常适合面向对象的编程(OOP),因为它支持通过组合(composition)与继承(inheritance)的方式定义类(class)。Python中没有访问说明符(access specifier,类似C++中的public和private),这么设计的依据是“大家都是成年人了”。

    l 在Python语言中,函数是第一类对象(firstclassobjects)。这指的是它们可以被指定给变量,函数既能返回函数类型,也可以接受函数作为输入。类(class)也是第一类对象。

    l Python代码编写快,但是运行速度比编译语言通常要慢。好在Python允许加入基于C语言编写的扩展,因此我们能够优化代码,消除瓶颈,这点通常是可以实现的。numpy就是一个很好地例子,它的运行速度真的非常快,因为很多算术运算其实并不是通过Python实现的。

    l Python用途非常广泛——网络应用,自动化,科学建模,大数据应用,等等。它也常被用作“胶水语言”,帮助其他语言和组件改善运行状况。

    l Python让困难的事情变得容易,因此程序员可以专注于算法和数据结构的设计,而不用处理底层的细节。

     

    2.这两个参数是什么意思:*args,**kwargs?我们为什么要使用它们?

    答案:如果我们不确定要往函数中传入多少个参数,或者我们想往函数中以列表和元组的形式传参数时,那就使要用*args;如果我们不知道要往函数中传入多少个关键词参数,或者想传入字典的值作为关键词参数时,那就要使用**kwargs。args和kwargs这两个标识符是约定俗成的用法,你当然还可以用*bob和**billy,但是这样就并不太妥。

     

    3.简要描述Python的垃圾回收机制(garbage collection)。

    答案:这里能说的很多。你应该提到下面几个主要的点:

    l Python在内存中存储了每个对象的引用计数(reference count)。如果计数值变成0,那么相应的对象就会小时,分配给该对象的内存就会释放出来用作他用。

    l 偶尔也会出现引用循环(reference cycle)。垃圾回收器会定时寻找这个循环,并将其回收。举个例子,假设有两个对象o1和o2,而且符合o1.x == o2和o2.x == o1这两个条件。如果o1和o2没有其他代码引用,那么它们就不应该继续存在。但它们的引用计数都是1。

    l Python中使用了某些启发式算法(heuristics)来加速垃圾回收。例如,越晚创建的对象更有可能被回收。对象被创建之后,垃圾回收器会分配它们所属的代(generation)。每个对象都会被分配一个代,而被分配更年轻代的对象是优先被处理的。

     


    4.|说说你对zen of python的理解,你有什么办法看到它?

    答案:Python之禅,Python秉承一种独特的简洁和可读行高的语法,以及高度一致的编程模

    式,符合“大脑思维习惯”,使Python易于学习、理解和记忆。Python同时采用了一条

    极简主义的设计理念,了解完整的Python哲学理念,可以在任何一个Python交互解释器

    中键入import this命令,这是Python隐藏的一个彩蛋:描绘了一系列Python设计原则。

    如今已是Python社区内流行的行话"EIBTI",明了胜于晦涩这条规则的简称. 在Python

    的思维方式中,明了胜于晦涩,简洁胜于复杂。

     

    5.是否遇到过python的模块间循环引用的问题,如何避免它?

    答案:这是代码结构设计的问题,模块依赖和类依赖

    如果老是觉得碰到循环引用,很可能是模块的分界线划错地方了。可能是把应该在一起的东西硬拆开了,可能是某些职责放错地方了,可能是应该抽象的东西没抽象

    总之微观代码规范可能并不能帮到太多,重要的是更宏观的划分模块的经验技巧,推荐uml,脑图,白板等等图形化的工具先梳理清楚整个系统的总体结构和职责分工采取办法,从设计模式上来规避这个问题,比如:

    1. 使用 “__all__”白名单开放接口

    2. 尽量避免 import

     

    6.有用过with statement吗?它的好处是什么?

    with open('text.txt') as myfile:

    ... while True:

    ... line = myfile.readline()

    ... if not line:

    ... break

    ... print line,

    #with语句使用所谓的上下文管理器对代码块进行包装,允许上下文管理器实现一些设置和清理操作。

    # 例如:文件可以作为上下文管理器使用,它们可以关闭自身作为清理的一部分。

    # NOTE:在PYTHON2.5中,需要使用from __future__ import with_statement进行with语句的导入

     

    7.Python里面search()和match()的区别

    >>> import re

    >>> re.match(r'python','Programing Python, should be pythonic')

    >>> obj1 = re.match(r'python','Programing Python, should be pythonic') #返回None

    >>> obj2 = re.search(r'python','Programing Python, should be pythonic') #找到pythonic

    >>> obj2.group()

    'python'

    #re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;#re.search匹配整个字符串,直到找到一个匹配。

     

     

     

    8.Python程序中文输出问题怎么解决

    在Python3中,对中文进行了全面的支持,但在Python2.x中需要进行相关的设置才能使用中文。否则会出现乱码。

    Python默认采取的ASCII编码,字母、标点和其他字符只使用一个字节来表示,但对于中文字符来说,一个字节满足不了需

    求。为了能在计算机中表示所有的中文字符,中文编码采用两个字节表示。如果中文编码和ASCII混合使用的话,就会导致解码错误,从而才生乱码。

    解决办法:

    交互式命令中:一般不会出现乱码,无需做处理

    py脚本文件中:跨字符集必须做设置,否则乱码

    1. 首先在开头一句添加:

    # coding = utf‐8

    # 或

    # coding = UTF‐8

    # 或

    # ‐*‐ coding: utf‐8 ‐*‐

    2. 其次需将文件保存为UTF‐8的格式!

    3. 最后: s.decode('utf‐8').encode('gbk')

     

     

    9.什么是lambda函数

    函数使用:

    1. 代码块重复,这时候必须考虑到函数,降低程序的冗余度

    2. 代码块复杂,这时候必须考虑到函数,降低程序的复杂度

    Python有两种函数,一种是def定义,一种是lambda函数()

    当程序代码很短,且该函数只使用一次,为了程序的简洁,及节省变量内存占用空间,引入了匿名函数这个概念

    >>> nums = range(2,20)

    >>> for i in nums:

    nums = filter(lambda x:x==i or x % i,nums)

    >>> nums

    [2, 3, 5, 7, 11, 13, 17, 19]

     

    10.Python里面如何拷贝一个对象

    切片S[:] # 注不能应用于字典

    深浅宝贝 # 能应用于所有序列和字典

    1. 浅拷贝D.copy()方法

    2. 深拷贝deepcopy(D)方法


    11.Python中pass语句的作用是什么

    pass语句什么也不做,一般作为占位符或者创建占位程序

     

    12.Python是如何进行内存管理的

    python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数,当对象被创建时就创建了一个引用计数,当对象不再需要时,这个对象的引用计数为0时,它被垃圾回收。所有这些都是自动完成,不需要像C一样,人工干预,从而提高了程序员的效率和程序的健壮性。

     

    13.Python异常处理介绍一下

    程序中出现异常情况时就需要异常处理。比如当你打开一个不存在的文件时。当你的程序中有一些无效的语句时,Python会提示你有错误存在。下面是一个拼写错误的例子,print写成了Print

    下面是异常最常见的几种角色

    1. 错误处理

    >>>可以在程序代码中捕捉和相应错误,或者忽略已发生的异常。

    >>>如果忽略错误,PYTHON默认的异常处理行为将启动:停止程序,打印错误信息。

    >>>如果不想启动这种默认行为,就用try语句来捕捉异常并从异常中恢复。

    2. 事件通知

    >>>异常也可用于发出有效状态的信号,而不需在程序间传递结果标志位。或者刻意对其进行测试

    3. 特殊情况处理

    >>>有时,发生了某种很罕见的情况,很难调整代码区处理。通常会在异常处理中处理,从而省去应对特殊情况的代码

    4. 终止行为

    >>>try/finally语句可确保一定会进行需要的结束运算,无论程序是否有异常

    5. 非常规控制流程

     

    14.介绍一下Python中的filter方法

    filter就像map,reduce,apply,zip等都是内置函数,用C语言实现,具有速度快,功能强大等

    优点。

    用于过滤与函数func()不匹配的值, 类似于SQL中select value != 'a'

    相当于一个迭代器,调用一个布尔函数func来迭代seq中的每个元素,返回一个是bool_seq返

    回为True的序列

    >>>第一个参数: function or None, 函数或None

    >>>第二个参数: sequence,序列

     

    15.介绍一下except的用法和作用

    try/except: 捕捉由PYTHON自身或写程序过程中引发的异常并恢复

    except: 捕捉所有其他异常

    except name: 只捕捉特定的异常

    except name, value: 捕捉异常及格外的数据(实例)

    except (name1,name2) 捕捉列出来的异常

    except (name1,name2),value: 捕捉任何列出的异常,并取得额外数据

    else: 如果没有引发异常就运行

    finally: 总是会运行此处代码

     

    16.inspect模块有什么用

    inspect模块提供了一系列函数用于帮助使用自省。

    检查对象类型

    is{module|class|function|method|builtin}(obj): 检查对象是否为模块、类、函数、方法、内建函数或方法。

    isroutine(obj): 用于检查对象是否为函数、方法、内建函数或方法等等可调用类型。

    获取对象信息

    getmembers(object[, predicate]): 这个方法是dir()的扩展版,它会将dir()找到的名字对应的属性一并返回。

    getmodule(object): 它返回object的定义所在的模块对象。

    get{file|sourcefile}(object): 获取object的定义所在的模块的文件名|源代码文件名(如果没有则返回None)。

    get{source|sourcelines}(object): 获取object的定义的源代码,以字符串|字符串列表返回。

    getargspec(func): 仅用于方法,获取方法声明的参数,返回元组,分别是(普通参数名的列表, *参数名, **参数名, 默认值元组)。

     

    17.Python列表与元组的区别是什么?分别在什么情况下使用?

    Python中列表和元组是序列,因此都能进行添加,删除,更新,切片等操作。但列表是可变对象,元祖是不可变对象。

    元祖主要用于函数赋值,字符串格式化等。但列表中的方法更多些,也是PYTHON中更常用的数据结构。

     

    18.解释一下python的and-or语法

    0 and *不需要再考虑*是0还是1,结果是0

    1 and *需要考虑*是0还是1来决定结果。

    1 or *不需要考虑后面的*,结果为1

    0 or *需要考虑后面的*来决定结果 这个语法看起来类似于 C 语言中的 bool ? a : b 表达式。整个表达式从左到右进行演算,所以先进行 and 表达式的演算。

    1 and 'first' 演算值为 'first',然后 'first' or 'second' 的演算值为 'first'。

    0 and 'first' 演算值为False,然后 0 or 'second' 演算值为 'second'。

    and‐or主要是用来模仿三目运算符 bool?a:b的,即当表达式bool为真,则取a否则取b。

    and‐or 技巧,bool and a or b 表达式,当a 在布尔上下文中的值为假时,不会像 C 语言表达式 bool ? a : b 那样工作。

     

    19.在Python中, list, tuple, dict, set有什么区别, 主要应用在什么样的场景?

    解答:定义list: 链表, 有序的项目, 通过索引进行查找, 使用方括号"[]";

    tuple: 元组, 元组将多样的对象集合到一起, 不能修改, 通过索引进行查找, 使用括号"()";

    dict: 字典, 字典是一组键(key)和值(value)的组合, 通过键(key)进行查找, 没有顺序, 使用大括号"{}";

    set: 集合,无序, 元素只出现一次, 自动去重, 使用"set([])";

    应用场景: 

    list, 简单的数据集合, 可以使用索引; 

    tuple, 把一些数据当做一个整体去使用, 不能修改;

    dict, 使用键值和值进行关联的数据;

    set, 数据只出现一次, 只关心数据是否出现, 不关心其位置;

    代码:

    mylist = [1, 2, 3, 4, 'Oh']  

    mytuple = (1, 2, 'Hello', (4, 5))  

    mydict = {'Wang' : 1, 'Hu' : 2, 'Liu' : 4}  

    myset = set(['Wang', 'Hu', 'Liu', 4, 'Wang'])

     

    20. 静态函数, 类函数, 成员函数的区别?

    解答:

    定义:

    静态函数(@staticmethod): 即静态方法,主要处理与这个类的逻辑关联;

    类函数(@classmethod): 即类方法, 更关注于从类中调用方法, 而不是在实例中调用方法, 可以用作方法重载, 传入参数cls;

    成员函数: 实例的方法, 只能通过实例进行调用;

    具体应用:

    日期的方法, 可以通过实例化(__init__)进行数据输出, 传入参数self;

    可以通过类的方法(@classmethod)进行数据转换, 传入参数cls;

    可以通过静态方法(@staticmethod)进行数据验证;

    代码:

    # -*- coding: utf-8 -*-  

    #eclipse pydev, python 3.3  

    #by C.L.Wang  

    class Date(object):  

        day = 0  

        month = 0  

        year = 0  

        def __init__(self, day=0, month=0, year=0):  

            self.day = day  

            self.month = month  

            self.year = year  

               

        def display(self):  

            return "{0}*{1}*{2}".format(self.day, self.month, self.year)  

          

     

     

        @classmethod  

        def from_string(cls, date_as_string):  

            day, month, year = map(int, date_as_string.split('-'))  

            date1 = cls(day, month, year)  

            return date1  

          

        @staticmethod  

        def is_date_valid(date_as_string):  

            day, month, year = map(int, date_as_string.split('-'))  

            return day <= 31 and month <= 12 and year <= 3999  

           

    date1 = Date('12', '11', '2014')  

    date2 = Date.from_string('11-13-2014')  

    print(date1.display())  

    print(date2.display())  

    print(date2.is_date_valid('11-13-2014'))  

    print(Date.is_date_valid('11-13-2014'))

     

    21. a=1, b=2, 不用中间变量交换a和b的值

    解答:

    两种形式: 加法或异或

    代码:

    a = 1  

    b = 2  

    a = a + b  

    b = a - b  

    a = a - b  

    print ('a = {0}, b = {1}'.format(a, b))  

    a = a ^ b  

    b = a ^ b  

    a = a ^ b  

    print ('a = {0}, b = {1}'.format(a, b))

     

    22. 写一个函数, 输入一个字符串, 返回倒序排列的结果: 如: string_reverse(‘abcdef’), 返回: ‘fedcba’(请采用多种方法实现, 并对实现方法进行比较)

    解答:

    5种方法的比较:

    1. 简单的步长为-1, 即字符串的翻转;

    2. 交换前后字母的位置;

    3. 递归的方式, 每次输出一个字符;

    4. 双端队列, 使用extendleft()函数;

    5. 使用for循环, 从左至右输出;

    代码:

    string = 'abcdef'  

    def string_reverse1(string):  

        return string[::-1]  

    def string_reverse2(string):  

        t = list(string)  

        l = len(t)  

        for i,j in zip(range(l-1, 0, -1), range(l//2)):  

            t[i], t[j] = t[j], t[i]  

        return "".join(t)  

    def string_reverse3(string):  

        if len(string) <= 1:  

            return string  

        return string_reverse3(string[1:]) + string[0]  

    from collections import deque  

    def string_reverse4(string):  

        d = deque()  

        d.extendleft(string)  

        return ''.join(d)  

    def string_reverse5(string):  

        #return ''.join(string[len(string) - i] for i in range(1, len(string)+1))  

        return ''.join(string[i] for i in range(len(string)-1, -1, -1))  

    print(string_reverse1(string))  

    print(string_reverse2(string))  

    print(string_reverse3(string))  

    print(string_reverse4(string))  

    print(string_reverse5(string))

     

    23.介绍一下python的异常处理机制

    解答:Python的异常处理机制:

    try: 尝试抛出异常;

    raise: 引发异常;

    except: 处理异常;

    finally: 是否发生异常都需要做的事情;

    创建新的异常类型, 需要继承Exception类, 可以定义类的属性, 便于处理异常;

    开发体会:

    异常主要处理读取文件, 也可以使用with的方法读取文件; 还可以用于网络连接, 异常可以包含大量的错误信息, 进行错误处理.

     

    代码:

    class ShortInputException(Exception):  

        def __init__(self, length, atleast):  

            Exception.__init__(self)  

            self.length = length  

            self.atleast = atleast  

               

    while True:  

        try:  

            text = raw_input('Enter somthing-->')  

            if len(text) < 3:  

                raise ShortInputException(len(text), 3)  

        except EOFError:  

            print('Why did you do an EOF on me')  

        except ShortInputException as ex:  

            print('ShortInputException The input was {0} long, \  

    excepted at least {1}. '.format(ex.length, ex.atleast))  

        else:  

            print('No exception was raised. ')  

        finally:  

            print('Over')

     

    24.Python自省

    这个也是python彪悍的特性.自省就是面向对象的语言所写的程序在运行时,所能知道对象的类型.简单一句就是运行时能够获得对象的类型.比如type(),dir(),getattr(),hasattr(),isinstance().

     

     

    25.Python中重载

    函数重载主要是为了解决两个问题。

    l 可变参数类型。

    l 可变参数个数。

    另外,一个基本的设计原则是,仅仅当两个函数除了参数类型和参数个数不同以外,其功能是完全相同的,此时才使用函数重载,如果两个函数的功能其实不同,那么不应当使用重载,而应当使用一个名字不同的函数。

    好吧,那么对于情况 1 ,函数功能相同,但是参数类型不同,python 如何处理?答案是根本不需要处理,因为python 可以接受任何类型的参数,如果函数的功能相同,那么不同的参数类型在 python 中很可能是相同的代码,没有必要做成两个不同函数。

    那么对于情况 2 ,函数功能相同,但参数个数不同,python 如何处理?大家知道,答案就是缺省参数。对那些缺少的参数设定为缺省参数即可解决问题。因为你假设函数功能相同,那么那些缺少的参数终归是需要用的。

    好了,鉴于情况 1 跟 情况 2 都有了解决方案,python 自然就不需要函数重载了。



    26.__new__和__init__的区别

    这个__new__确实很少见到,先做了解吧.

    l __new__是一个静态方法,而__init__是一个实例方法.

    l __new__方法会返回一个创建的实例,而__init__什么都不返回.

    l 只有在__new__返回一个cls的实例时后面的__init__才能被调用.

    l 当创建一个新实例时调用__new__,初始化一个实例时用__init__.

    stackoverflow

    ps: __metaclass__是创建类时起作用.所以我们可以分别使用__metaclass__,__new__和__init__来分别在类创建,实例创建和实例初始化的时候做一些小手脚.


    27.GIL线程全局锁

    线程全局锁(Global Interpreter Lock),即Python为了保证线程安全而采取的独立线程运行的限制,说白了就是一个核只能在同一时间运行一个线程.

    解决办法就是多进程和下面的协程(协程也只是单CPU,但是能减小切换代价提升性能).

     

    28.协程

    简单点说协程是进程和线程的升级版,进程和线程都面临着内核态和用户态的切换问题而耗费许多切换时间,而协程就是用户自己控制切换的时机,不再需要陷入系统的内核态.

    Python里最常见的yield就是协程的思想!可以查看第九个问题.


    29.闭包

    闭包(closure)是函数式编程的重要的语法结构。闭包也是一种组织代码的结构,它同样提高了代码的可重复使用性。

    当一个内嵌函数引用其外部作作用域的变量,我们就会得到一个闭包. 总结一下,创建一个闭包必须满足以下几点:

    l 必须有一个内嵌函数

    l 内嵌函数必须引用外部函数中的变量

    l 外部函数的返回值必须是内嵌函数

    感觉闭包还是有难度的,几句话是说不明白的,还是查查相关资料.

    重点是函数运行后并不会被撤销,就像16题的instance字典一样,当函数运行完后,instance并不被销毁,而是继续留在内存空间里.这个功能类似类里的类变量,只不过迁移到了函数上.

    闭包就像个空心球一样,你知道外面和里面,但你不知道中间是什么样.



    30.Python垃圾回收机制

    Python GC主要使用引用计数(reference counting)来跟踪和回收垃圾。在引用计数的基础上,通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用问题,通过“分代回收”(generation collection)以空间换时间的方法提高垃圾回收效率。

    1 引用计数

    PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少.引用计数为0时,该对象生命就结束了。

    优点:

    简单

    实时性

    缺点:

    维护引用计数消耗资源

    循环引用

    2 标记-清除机制

    基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的引用出发,遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没标记的对象释放。

    3 分代技术

    分代回收的整体思想是:将系统中的所有内存块根据其存活时间划分为不同的集合,每个集合就成为一个“代”,垃圾收集频率随着“代”的存活时间的增大而减小,存活时间通常利用经过几次垃圾回收来度量。

    Python默认定义了三代对象集合,索引数越大,对象存活时间越长。

    举例:
    当某些内存块M经过了3次垃圾收集的清洗之后还存活时,我们就将内存块M划到一个集合A中去,而新分配的内存都划分到集合B中去。当垃圾收集开始工作时,大多数情况都只对集合B进行垃圾回收,而对集合A进行垃圾回收要隔相当长一段时间后才进行,这就使得垃圾收集机制需要处理的内存少了,效率自然就提高了。在这个过程中,集合B中的某些内存块由于存活时间长而会被转移到集合A中,当然,集合A中实际上也存在一些垃圾,这些垃圾的回收会因为这种分代的机制而被延迟。

     

    31.read,readline和readlines

    l  read 读取整个文件

    l  readline 读取下一行,使用生成器方法

    l  readlines 读取整个文件到一个迭代器以供我们遍历

     

    32.简述函数式编程

    在函数式编程中,函数是基本单位,变量只是一个名称,而不是一个存储单元。除了匿名函数外,Python还使用fliter(),map(),reduce(),apply()函数来支持函数式编程。

     

    33.什么是匿名函数,匿名函数有什么局限性

    匿名函数,也就是lambda函数,通常用在函数体比较简单的函数上。匿名函数顾名思义就是函数没有名字,因此不用担心函数名冲突。不过Python对匿名函数的支持有限,只有一些简单的情况下可以使用匿名函数。


    34.如何捕获异常,常用的异常机制有哪些?

    如果我们没有对异常进行任何预防,那么在程序执行的过程中发生异常,就会中断程序,调用python默认的异常处理器,并在终端输出异常信息。

    try…except…finally语句:当try语句执行时发生异常,回到try语句层,寻找后面是否有except语句。找到except语句后,会调用这个自定义的异常处理器。except将异常处理完毕后,程序继续往下执行。finally语句表示,无论异常发生与否,finally中的语句都要执行。

    assert语句:判断assert后面紧跟的语句是True还是False,如果是True则继续执行print,如果是False则中断程序,调用默认的异常处理器,同时输出assert语句逗号后面的提示信息。

    with语句:如果with语句或语句块中发生异常,会调用默认的异常处理器处理,但文件还是会正常关闭。

     

    35.copy()与deepcopy()的区别

    copy是浅拷贝,只拷贝可变对象的父级元素。 deepcopy是深拷贝,递归拷贝可变对象的所有元素。

     

    36.函数装饰器有什么作用

    装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:**日志、性能测试、事务处理、缓存、权限校验等场景。有了装饰器,就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。

     

    37.简述Python的作用域以及Python搜索变量的顺序

    Python作用域简单说就是一个变量的命名空间。代码中变量被赋值的位置,就决定了哪些范围的对象可以访问这个变量,这个范围就是变量的作用域。在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域。Python的变量名解析机制也称为 LEGB 法则:本地作用域(Local)→当前作用域被嵌入的本地作用域(Enclosing locals)→全局/模块作用域(Global)→内置作用域(Built-in)

    新式类和旧式类的区别,如何确保使用的类是新式类

    为了统一类(class)和类型(type),python在2.2版本引进来新式类。在2.1版本中,类和类型是不同的。

    为了确保使用的是新式类,有以下方法:

    放在类模块代码的最前面 __metaclass__ = type
    从内建类object直接或者间接地继承
    在python3版本中,默认所有的类都是新式类。

    简述__new__和__init__的区别

    创建一个新实例时调用__new__,初始化一个实例时用__init__,这是它们最本质的区别。

    new方法会返回所构造的对象,init则不会.

    new函数必须以cls作为第一个参数,而init则以self作为其第一个参数.

     

    38.Python垃圾回收机制

    Python GC主要使用引用计数(reference counting)来跟踪和回收垃圾。在引用计数的基础上,通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用问题,通过“分代回收”(generation collection)以空间换时间的方法提高垃圾回收效率。

     

    1 引用计数

    PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少.引用计数为0时,该对象生命就结束了。

    优点:简单 实时性

    缺点:维护引用计数消耗资源 循环引用

    2 标记-清除机制

    基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的引用出发,遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没标记的对象释放。

    3 分代技术

    分代回收的整体思想是:将系统中的所有内存块根据其存活时间划分为不同的集合,每个集合就成为一个“代”,垃圾收集频率随着“代”的存活时间的增大而减小,存活时间通常利用经过几次垃圾回收来度量。

    Python默认定义了三代对象集合,索引数越大,对象存活时间越长。

     

    39.Python中的@property有什么作用?如何实现成员变量的只读属性?

    @property装饰器就是负责把一个方法变成属性调用,通常用在属性的get方法和set方法,通过设置@property可以实现实例成员变量的直接访问,又保留了参数的检查。另外通过设置get方法而不定义set方法可以实现成员变量的只读属性。

    *args and **kwargs

    *args代表位置参数,它会接收任意多个参数并把这些参数作为元组传递给函数。**kwargs代表的关键字参数,允许你使用没有事先定义的参数名,另外,位置参数一定要放在关键字参数的前面。

    有用过with statement吗?它的好处是什么?具体如何实现?

    with语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等。

     

    40. Python是如何进行内存管理的?

    答:从三个方面来说,一对象的引用计数机制,二垃圾回收机制,三内存池机制

    一、对象的引用计数机制

    Python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数。

    引用计数增加的情况:

    1,一个对象分配一个新名称

    2,将其放入一个容器中(如列表、元组或字典)

    引用计数减少的情况:

    1,使用del语句对对象别名显示的销毁

    2,引用超出作用域或被重新赋值

    sys.getrefcount( )函数可以获得对象的当前引用计数

    多数情况下,引用计数比你猜测得要大得多。对于不可变数据(如数字和字符串),解释器会在程序的不同部分共享内存,以便节约内存。

    二、垃圾回收

    1,当一个对象的引用计数归零时,它将被垃圾收集机制处理掉。

    2,当两个对象a和b相互引用时,del语句可以减少a和b的引用计数,并销毁用于引用底层对象的名称。然而由于每个对象都包含一个对其他对象的应用,因此引用计数不会归零,对象也不会销毁。(从而导致内存泄露)。为解决这一问题,解释器会定期执行一个循环检测器,搜索不可访问对象的循环并删除它们。

    三、内存池机制

    Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统

    1,Pymalloc机制。为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。

    2,Python中所有小于256个字节的对象都使用pymalloc实现的分配器,而大的对象则使用系统的malloc。

    3,对于Python对象,如整数,浮点数和List,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。

     

    41. 什么是lambda函数?它有什么好处?

    答:lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数

    lambda函数:首要用途是指点短小的回调函数

    lambda [arguments]:expression

    >>> a=lambdax,y:x+y

    >>> a(3,11)

     

     

    42.Python里面如何拷贝一个对象?(赋值,浅拷贝,深拷贝的区别)

    答:赋值(=),就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个。

    浅拷贝:创建一个新的对象,但它包含的是对原始对象中包含项的引用(如果用引用的方式修改其中一个对象,另外一个也会修改改变){1,完全切片方法;2,工厂函数,如list();3,copy模块的copy()函数}

    深拷贝:创建一个新的对象,并且递归的复制它所包含的对象(修改其中一个,另外一个不会改变){copy模块的deep.deepcopy()函数}

     

    43.介绍一下except的用法和作用?

    答:try…except…except…[else…][finally…]

    执行try下的语句,如果引发异常,则执行过程会跳到except语句。对每个except分支顺序尝试执行,如果引发的异常与except中的异常组匹配,执行相应的语句。如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。

    try下的语句正常执行,则执行else块代码。如果发生异常,就不会执行

    如果存在finally语句,最后总是会执行。

    44. Python中pass语句的作用是什么?

    答:pass语句不会执行任何操作,一般作为占位符或者创建占位程序,whileFalse:pass

    45.介绍一下Python下range()函数的用法?

    答:列出一组数据,经常用在for  in range()循环中、

    46.如何用Python来进行查询和替换一个文本字符串?

    答:可以使用re模块中的sub()函数或者subn()函数来进行查询和替换,

    格式:sub(replacement, string[,count=0])(replacement是被替换成的文本,string是需要被替换的文本,count是一个可选参数,指最大被替换的数量)

    >>> import re

    >>>p=re.compile(‘blue|white|red’)

    >>>print(p.sub(‘colour’,'blue socks and red shoes’))

    colour socks and colourshoes

    >>>print(p.sub(‘colour’,'blue socks and red shoes’,count=1))

    colour socks and redshoes

    subn()方法执行的效果跟sub()一样,不过它会返回一个二维数组,包括替换后的新的字符串和总共替换的数量

     
    47.Python里面match()和search()的区别?

    答:re模块中match(pattern,string[,flags]),检查string的开头是否与pattern匹配。

    re模块中research(pattern,string[,flags]),在string搜索pattern的第一个匹配值。

    >>>print(re.match(‘super’, ‘superstition’).span())

    (0, 5)

    >>>print(re.match(‘super’, ‘insuperable’))

    None

    >>>print(re.search(‘super’, ‘superstition’).span())

    (0, 5)

    >>>print(re.search(‘super’, ‘insuperable’).span())

    (2, 7)


    48.单引号,双引号,三引号的区别

    答:单引号和双引号是等效的,如果要换行,需要符号(\),三引号则可以直接换行,并且可以包含注释

    如果要表示Let’s Go 这个字符串

    单引号:s4 = ‘Let\’s go’

    双引号:s5 = “Let’s go”

    s6 = ‘I realy like“python”!’

    这就是单引号和双引号都可以表示字符串的原因了

     

     

     


     

    展开全文
  • 那就是巩固基础--系统的学习python初级、高级语法,一段时间后,我明显感觉到自己的代码变得更简洁、优美,coding的心情也变的舒畅~ 就此分享一波仓库的资料:包含Python基础知识的14张思维导图-PDF,希望有所帮助...
  • python基础知识学习总结从零开始学习python,已经学习完python相关的基础教程,学习地址详见:http://www.runoob.com/python/python-tutorial.html基础教程主要学习了python的特性、变量类型、控制语句、数据结构...
  • python基础知识这个系列中,准备罗列出我学习python的一些基础知识,包括: 基本语法控制语句内置数据结构模块和函数字符串文件处理面向对象异常处理 以前写机器学习算法喜欢使用Matlab语言,接触python后,觉得...
  • Python基础知识笔试

    2017-10-10 20:28:22
    Python基础知识笔试   单选题(2.5分*20题) 1. 下列哪个表达式在Python中是非法的? B A. x = y = z = 1 B. x = (y = z + 1) C. x, y = y, x D. x += y 2. python my.py v1 v2 命令运行脚本,通过...
  • python基础知识点总结

    2019-03-17 20:36:49
    Python简介 1.计算机 1.1 计算机概念 计算机【computer】俗称电脑,是现代一种用于高速计算的电子机器。 1.2 计算机组成 计算机由硬件系统与软件系统组成。 计算机硬件系统包含: 运算器:用于进行计算的...
  • 前几天整理了一下Python面向对象部分,今天决定把其他的基础部分也分享出来: 有问题请留言~很感谢~ 还有,祝大家520快乐~永远幸福~
  • python基础知识归纳

    2018-05-16 09:24:49
    一些跟java不一样的点:[] list:元素是什么都行() tuple:不可编辑{} 字典,类似json字符串获取输入:a = input("请输入XXX:")输入的东西默认是个字符串,如果想要转化的话,可以:a=int(a)swap:a , b=b ,...
  • 缩进是指每行语句前的空白区域,用来表示Python程序间的包含和层次关系。 一般语句不需要缩进,顶行书写且不留空白。 当表示分支、循环、函数、类等含义,在if,while,for,def,class等保留字所在的完整语句后...
  • Python基础知识归纳

    2019-05-18 10:38:18
    Python 基础教程 Python 基础教程 Python 简介 Python 环境搭建 Python 中文编码 Python 基础语法 Python 变量类型 Python 运算符 Python 条件语句 Python 循环语句 Python While 循环语句 Python for ...
  • 欢迎喜欢数据分析的小伙伴可以关注一下微信公众号,公众号里面主要介绍各种数据分析技能
  • python基础知识刷题

    2018-07-25 10:37:27
    1,执行Python脚本的两种方式 1 2 3 4 五 交互方式:命令行   Windows操作系统下,快捷键cmd,输入“python”启动交互式python解释器。   文件方式:python文件 ...
  • 目录Python基础知识详解 从入门到精通(一)简介Python 的各种发行版开发环境 Python基础知识详解 从入门到精通(一) 本篇主要是介绍python,内容可先看目录 其他基础知识详解,欢迎查看本人的另一篇文章 简介 ...
  • 如果初学者接触的第一门语言是Python,学习曲线则会平滑得多,掌握一些基本语法和Python内置的数据结构,已经可以上手写一些小工具或者小型应用。这对初学者来说,非常重要。因为学习的过程是一个突破舒适区的过程,...
  • 作者:叽里咕噜ii链接:...接下来你需要选定选定一个方向,Python有一个别称叫“胶水语言”,意思就是它可以干很多事情,比如现在经常听到的的AI,Python就被广泛应用其中,其他的比如web开发、机器学习/深...
1 2 3 4 5 ... 20
收藏数 163,545
精华内容 65,418
热门标签
关键字:

python基础知识