【学习笔记】python基础,这一篇就够了!!

文章目录

          • 语法基础
          • 判断语句和循环语句
          • 列表
          • 元组
          • 字典
          • 拆包
          • 函数
          • 文件操作
          • 面向对象基础
          • 异常
          • 模块

语法基础
  • 注释
    • 单行注释 #
    • 多行注释 “"" xxx “”"
  • 变量类型
    type(V_name) 查看变量类型
    不同的变量类型,占用的内存大小不同
    • Numbers
      • 整形 int
      • 长整型 long
      • 浮点型 float
      • 复数 complex
    • 布尔型 bool
    • 字符串 str
    • 列表 List
    • 元组 Tuple
    • 字典 Dictionary
  • 标识符
    由字母,下划线和数字组成,且数字不能开头
    区分大小写
  • 关键词
    特殊功能的标识符

‘False’, ‘None’, ‘True’, ‘__peg_parser__’, ‘and’, ‘as’, ‘assert’, ‘async’, ‘await’, ‘break’, ‘class’, ‘continue’, ‘def’, ‘del’, ‘elif’, ‘else’, ‘except’, ‘finally’, ‘for’, ‘from’, ‘global’, ‘if’, ‘import’, ‘in’, ‘is’, ‘lambda’, ‘nonlocal’, ‘not’, ‘or’, ‘pass’, ‘raise’, ‘return’, ‘try’, ‘while’, ‘with’, ‘yield’

  • 输出
    • 格式化输出
      格式化常用符号
      • %s 格式化字符串
      • %d 格式化整数
      • %-2d 显示两位并左对齐,若只有一位则用空格占位,默认右对齐
      • %f 格式化浮点数字,可指定小数点后的精度
      myAge = 20
      print("我的年龄是%d岁" % myAge)
    
    • 转义输出
      常用转义字符
      • \n 换行符
      • \t 横向制表符(TAB)
      • \0 表示一个空字符
      • \v 纵向制表符
      • \r 回车符
      • \f 换页符
  • 输入
    input得到的结果是String
myName = input("please enter your Name:")
myAge = input("please enter your Age:")
print("Name:%s Age:%s" % (myName,myAge))
  • 运算符

    • 算术运算符
      + 加;- 减;* 乘;/ 除;// 整除;% 取余;** 指数
    • 赋值运算符 =
    • 复合赋值运算符
      算术运算符复合赋值运算符
    • 关系运算符
      ==;!=;>;<;>=;<=
    • 逻辑运算符
      and;or;not
  • 常用数据类型转换

    • int(x) 将x转换为一个整数
    • float(x) 将x转换为一个浮点数
    • str(x) 将x转换为一个字符串
    • eval(str) 用来计算在字符串中的有效python表达式,并返回一个对象
判断语句和循环语句
  • if-elif-else
if 判断条件1:
    执行语句1
elif 判断条件2:
    执行语句2
else:
    执行语句3
  • if嵌套(采用缩进区分层次)
money = eval(input("请输入您公交卡的余额:"))
flag = not True
if money >= 2:
    print("可以上公交车")
    if flag:
        print("可以坐下")
    else:
        print("站一会")
else:
    print("请充值后再上车")
  • while循环
while 判断条件:
    执行语句
    循环标识+1  
  • while循环嵌套
#九九乘法表
x = 1
while x <= 9:
    # 定义一个变量 记录列数
    y = 1
    while y <= x:
        print("%d * %d = %-2d" % (y, x, x * y), end="  ")
        y += 1
    # 换行
    print()
    x += 1
  • for循环
    范围函数range()
    range(m,n) -> [m,n)
    range(n) -> [0,n)
for 临时变量 in 可迭代对象(列表/字符串/...:
    执行语句
  • break&continue
    break:结束所有循环
    continue:提前结束本次循环,进入下一次循环
  • for-else&while-else
for i in range(5):
    print(i)
    if i == 2:
        #break
    else:
        print("else")

# while循环
i = 0
while i < 5:
    print(i)
    if i == 2:
        break
    i += 1
else:
    print("else")

"""
无论for-else  还是 while-else 如果在for循环中 或者 while循环中 没有执行break 待for循环或者while结束后 会执行else中的代码
当for循环或者while循环中的break执行 else中的代码将不会执行
"""
  • 字符串
    字符串 -> 有序的字符序列
    • 索引
      从左到右0,1,2…
      从右到左-1,-2,-3…
    • 切片 [start,end,step] 范围[start,end)
    • 常见操作
      • len(str) 获取字符串长度
      • mystr = “”“文本内容”"" 保留拷贝的文本格式
      • mystr.find(“str”) 获取对应字符串的下标索引,如果未查询到,返回-1;
      • mystr.index(“str”) 获取对应字符串的下标索引,如果未查询到,返回异常;
      • mystr.count(str,start=0,end=len(myStr)) 返回str在start和end之间在mystr中出现的次数;
      • mystr.replace(str1,str2,n) 把myStr中的str1替换成str2;如果n指定,则不超过n次;
      • mystr.split(str=" ",2) 以str为分隔符,切片mystr,返回一个列表;如果n指定,则仅分隔n个字符串;
      • mystr.capitalize() 把字符串的第一个字符大写;
      • mystr.title() 把字符串的每个单词首字母大写;
      • mystr.startswith(obj)检查字符串是否是以 obj开头, 是则返回 True,否则返回 False;
      • mystr.endswith(obj) 检查字符串是否以obj结束,如果是返回True,否则返回 False;
      • mystr.lower() 转换字符串中所有大写字符为小写;
      • mystr.upper() 转换字符串中的小写字母为大写;
      • mystr.ljust(width,fillchar) 返回一个原字符串左对齐,并使用指定fillchar[默认空格]填充至长度 width 的新字符串
      • mystr.rjust(width,fillchar) 返回一个原字符串右对齐,并使用指定fillchar[默认空格]填充至长度 width 的新字符串
      • mystr.center(width,fillchar) 返回一个原字符串居中,并使用指定fillchar[默认空格]填充至长度 width 的新字符串
      • mystr.lstrip() 删除 mystr 左边的空白字符
      • mystr.rstrip() 删除 mystr 字符串末尾的空白字符
      • mystr.strip() 删除mystr字符串两端的空白字符
      • mystr.rfind(str, start=0,end=len(mystr) ) 类似于find(),不过是从右边开始.
      • mystr.rindex( str, start=0,end=len(mystr)) 类似于 index(),不过是从右边开始
      • mystr.partition(str) 把mystr以str分割成三部分,str前,str和str后
      • mystr.rpartition(str) 类似于 partition()函数,不过是从右边开始.
      • mystr.splitlines() 按照行分隔,返回一个包含各行作为元素的列表
      • mystr.isalpha() 如果 mystr 所有字符都是字母 则返回 True,否则返回 False
      • mystr.isdigit() 如果 mystr 只包含数字则返回 True 否则返回 False.
      • mystr.isalnum() 如果 mystr 所有字符都是字母或数字则返回 True,否则返回 False
      • mystr.isspace() 如果 mystr 中只包含空格,则返回 True,否则返回 False.
      • mystr.join(str) mystr中每个元素后面插入str,构造出一个新的字符串
列表
  • 定义
    my_list =[元素1,元素2,…]
  • 索引
    • 从左到右0,1,2…
    • 从右到左-1,-2,-3…
  • 列表的循环遍历
    • for循环
    • while循环
namesList = ['xiaoWang','xiaoZhang','xiaoHua']
for name in namesList:
    print(name)
    
length = len(namesList)
i = 0
while i<length:
    print(namesList[i])
    i+=1
  • 常见操作
    • 添加元素
      • append
        添加一个整体
      • extend
        添加一个可以遍历的对象;将另一个集合中的元素逐一添加到列表中
      • insert(index, object)
        在指定位置index前插入元素object
    >>> a = [1, 2]
    >>> b = [3, 4]
    >>> a.append(b)
    >>> a
    [1, 2, [3, 4]]
    
    >>> a.extend(b)
    >>> a
    [1, 2, [3, 4], 3, 4]
    
    >>> a.insert(1, 3)
    >>> a
    [1, 3, 2, [3, 4], 3, 4]
    
    • 修改元素
    A = ['xiaoWang','xiaoZhang','xiaoHua']
    
    #修改元素
    A[1] = 'xiaoLu'
    
    • 查找元素
      • in, not in
      nameList = ['xiaoWang','xiaoZhang','xiaoHua']
      
      findName = input('请输入要查找的姓名:')
      
      #查找是否存在
      if findName in nameList:
          print('找到了')
      else:
          print('没有找到')
      
      • index
        返回查找元素的下标索引
      • count
      >>> a = ['a', 'b', 'c', 'a', 'b']
      >>> a.index('a', 1, 3) # 注意是左闭右开区间
      Traceback (most recent call last):
        File "", line 1, in <module>
      ValueError: 'a' is not in list
      >>> a.index('a', 1, 4)
      3
      
      >>> a.count('b')
      2
      >>> a.count('d')
      0
      
    • 删除元素
      • del
        根据下标进行删除
        可以用来删除对象,提前释放内存
      • pop
        删除最后一个元素,且会有一个返回值
      • remove
        根据元素的值进行删除
      movieName = ['加勒比海盗','骇客帝国','第一滴血','指环王','霍比特人','速度与激情']
      
      del movieName[2] #根据下标进行删除
      
      movieName.pop() #删除最后一个元素
      
      movieName.remove('指环王') #根据元素的值进行删除
      
    • 排序
      sort,reverse
    >>> a = [1, 4, 2, 3]
    >>> a
    [1, 4, 2, 3]
    >>> a.reverse() #降序
    >>> a
    [3, 2, 4, 1]
    >>> a.sort()
    >>> a
    [1, 2, 3, 4]
    >>> a.sort(reverse=True)
    >>> a
    [4, 3, 2, 1]
    
  • 列表的嵌套
schoolNames = [['北京大学','清华大学'],['南开大学','天津大学','天津师范大学'],['山东大学',["新东方", "蓝翔"],'中国海洋大学']]

name = schoolNames[1][1]
print(name)
元组

列表是可变的,元组是不可变的

  • 定义
    my_tuple = (元素1,元素2,…)
  • 注意
    如果元组只有一个元素,不为元组类型;可以加个逗号
    (1)–> int;(1,)–>tuple
  • 常见操作
    • 访问元组
      通过下标索引
    • 查找元素
      • index
      • count
字典

键值对{key:value,…};字典是无序的,可变的

  • 定义
    my_dict = {key1:value1,key2:value2,…}
    key值类型必须是不可变的(如列表、字典等都不可),且不能重复(才能完成1对1),一般都使用字符串

  • 常见操作

    • 修改元素/添加元素
      格式:字典名[key] = value
      如果key不存在,则添加一组键值对;如果key存在,则会覆盖此key原来的值

    • 删除元素

      • del
        删除指定元素,也可以删除整个字典
      • clear
        清空整个字典
      >>> info = {
               'name':'班长', 'sex':'f', 'address':'地球亚洲中国北京'}
      
      >>> del info['name']
      
      >>> print('删除后,%s' % info['name'])
      Traceback (most recent call last):
        File "", line 1, in <module>
      KeyError: 'name'
      
      del info #删除整个字典
      
      info.clear() #清空整个字典 结果为{}
      
    • len() 返回键值对的个数

    • keys 返回一个包含字典所有key的列表

    • values 返回一个包含字典所有value的列表

    • items 返回一个包含所有(键,值)元祖的列表

  • 遍历

my_dict = {
     "name": "小红", "age": 22, "no": "009"}

# 遍历-key
for key in my_dict.keys():
    print(key)

# 遍历value
for value in my_dict.values():
    print(value)

# 遍历items
for item in my_dict.items():
    print(item[0])

# 通过设置两个临时变量
for key, value in my_dict.items():
    print("key:", key)
    print("value:", value)

# enumerate(列表名) 函数
# enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标
my_list = list("abcd")
# 不仅要获取列表中的元素 而且需要知道这个元素下标索引
for i, value in enumerate(my_list):
    print(i,value)
拆包

变量名和值一一对应
可以把函数返回值直接拆包

name,age,no,address = ("zhangsan",20,1,"didian")

name,age,no,address = ["zhangsan",20,1,"didian"]

name,age,no,address = {
     "name":"zhangsan","age":20,"no":1,"address":"didian"} #取到的是key值

#批量定义变量
num1, num2, num3, num4 = 10, 20, 30, 40
函数
  • 定义
def 函数名(形参1,形参2...):
       函数体
# pass占位,防止错误
  • 调用
函数名(实参1,实参2...)
  • 缺省参数
    给形参设置一个默认值;调用函数时,可根据实际需要决定是否传递参数必须先定义后调用,有先后顺序
    注意:在定义函数时若某个形参使用了缺省参数,那么其后面的形参都需要用缺省参数
  • 四种函数类型
    • 无参数、无返回值
    • 无参数、有返回值
    • 有参数、无返回值
    • 有参数、有返回值
  • 函数可嵌套调用
  • 调用函数方式
    • 位置参数
      使用位置参数调用函数,需要注意实参的位置–>实参的位置需要和形参的位置一一对应
    • 关键字参数
      调用函数的时候使用的是函数的形参名,位置不需要完全对应
  • 函数返回值return
    只要函数中执行了return,提前结束函数的执行,且其后的代码将不再执行;可以通过return使执行的函数提前结束以优化性能
    可以直接返回不同类型的数据;如return a,b --> tuple return […] --> list ; return{ “key”:value,“key2”:value,…} --> dict ;
  • 函数的文档说明
    • 如果一个自定义函数没有文档说明 ,默认用help会打印函数上面的注释
    • 可以在def下方用""" “”"自动生成文档说明
  • 变量
    • 局部变量
      定义在函数内部,作用域仅在函数内部
    • 全局变量
      定义在函数外部,作用域为整个模块;
      标识全局变量 --> global 变量名
    • 优先级
      局部变量>全局变量;python会现在函数内部找变量,若无,再在外部找
  • 匿名函数lambda
# 对函数的简写

f = lambda a, b : a + b
print(f(10, 20))

# 等价于
# def add2num(a, b):
#     return a + b


# 函数作为参数传递

# f = lambda x,y:x+y

def fun(a, b, opt):
    result = opt(a, b)
    print("result = %d" % result)

fun(1, 2, lambda x,y:x+y)


# 自定义排序(最外层肯定是列表)
# 格式: 列表名.sort(key=lambda 列表的元素(临时变量): 临时变量[key])

stus = [{
     "name": "zhangsan", "age": 18}, {
     "name": "lisi", "age": 19}, {
     "name": "wangwu", "age": 17}]

# 按照年龄排序
stus.sort(key=lambda my_dict:my_dict["age"])

# 按照名字排序
stus.sort(key=lambda my_dict:my_dict["name"])

# 列表中的列表嵌套
my_list = [[10, 8, 9], [7, 10, 19], [9, 10, 29]]
# 按照列表元素(小列表)最后一个元素排序
my_list.sort(key=lambda new_list:new_list[2], reverse=True)
  • 列表推导式
    快速创建有规律的列表
# 使用列表推导式 快速创建一个列表
my_list = [ i for i in range(1, 31)]

# 等价于
# my_list = []
# for i in range(1, 101):
#     my_list.append(i)


# 得到一个有30个哈哈的列表
  my_list = ["哈哈" for i in range(30)]


# 定义一个列表 保存数据[1, 50]之间的偶数
# 列表推导式
my_list = [ i for i in range(1, 51) if i % 2 == 0]

# 等价于
# my_list = []
# for i in range(1, 51):
#     # 判断是否是偶数
#     if i % 2 == 0:
#         my_list.append(i)
#
# print(my_list)
文件操作
  • 文件打开与关闭
# 打开一个文件 以只读方式 返回一个文件对象
# 如果使用r模式打开文件,如果文件存在,直接打开;如果文件不存在 会报错
f = open("hm.txt", "r")

# 关闭文件(打开一个文件就需要消耗内存)
f.close()

# 打开一个文件 以只写方式 返回一个文件对象;如果以w方式打开文件 会把原来文件的数据清空 然后在写入
# 如果使用w模式打开文件 如果文件存在 直接打开;如果文件不存在 会创建一个文件 然后打开
open("hm.txt", "w")
f.close()

# a 追加数据
# f = open(file_name, "a")
# f.write("nihao")
# f.close()
  • 文件读写
file_name = "hm.txt"
# <1>写数据(write)
# f = open(file_name, "w")
# f.write("hello world")
# f.close()

# <2>读数据(read) 如果使用字符串方便
# f = open(file_name, "r")
# ret = f.read()
# print(ret)
# f.close


# <3>读数据(readlines) 如果使用列表方便
# f = open(file_name, "r")
# 把每行的数据保存到列表中
# ret = f.readlines()
# print(ret)
# f.close()

# 中文读写
# f = open("hmhm.txt", "w", encoding="utf-8")
# # 写入数据
# # 默认情况下如果在windows电脑中(中国) 保存中文编码格式为gbk (mac电脑或者是linux 没有问题)
# # 如果其他字符 例如abcd 编码格式为utf-8
# f.write("你好世界")
# # 关闭文件
# f.close()
  • 其他操作
    导入os模块
import os
# 文件/文件夹重命名
os.rename(old_fileName,new_fileName)

# 删除文件
os.remove(fileName)

# 创建文件夹
os.mkdir(dirName)

# 获取当前目录(绝对路径)
result = os.getwd()

# 改变默认目录
os.chdir("../")

# 获取目录列表
my_list = os.listdir()

# 删除文件夹
os.rmdir(dirName)
  • 其他类型文件操作
    • txt文件
    # 读取
    # 通过此方式打开文件 不需要关闭
    # as 是给文件起了名字
    with open("hm.txt", "r", encoding="utf-8") as f:
        result = f.read()
            
    # 写入
    f = open("hm.txt", "w", encoding="utf-8")
    f.write("hello python!!!")
    f.close()
    
    • excel文件
    # 读取
    import xlrd
    data = xlrd.open_workbook("student.xlsx")
    # 获取列表
    table = data.sheet_by_index(0)
    # 获取所有的行数
    nrows = table.nrows
    # 获取所有的列数
    ncols = table.ncols
    
    # 获取第一行的数据
    first_row_name_list = table.row_values(0)
    print(first_row_name_list)
    
    # 定义一个列表保存所有行的数据
    info_list = []
    # 遍历所有行
    for rownum in range(1, nrows):
        row = table.row_values(rownum)
        if row:
            info_list.append(row)
    
    print(info_list)
    
    
    # 写入
    import xlsxwriter
    # 打开student.xlsx文件
    workbook = xlsxwriter.Workbook("student.xlsx")
    # 创建一张工作表
    worksheet = workbook.add_worksheet()
    # 设置第一行信息
    worksheet.write(0, 0, "学号")
    worksheet.write(0, 1, "姓名")
    worksheet.write(0, 2, "年龄")
    
    # 学生信息列表
    student_list = [{
           "name": "小明", "age": 20, "no": "20170901001"},
                    {
           "name": "小红", "age": 21, "no": "20170901002"},
                    {
           "name": "小刚", "age": 20, "no": "20170901003"},
                    {
           "name": "小海", "age": 23, "no": "20170901004"},
                    {
           "name": "小阳", "age": 25, "no": "20170901005"}]
    
    # 遍历列表
    for i, info in enumerate(student_list):
        # 写入数据
        # write(第x行, 第x列, 写入的数据)
        worksheet.write(i + 1, 0, info["no"])
        worksheet.write(i + 1, 1, info["name"])
        worksheet.write(i + 1, 2, info["age"])
    
    # 关闭文件
    workbook.close()
    
    • json文件
    # 读取
    import json
    
    # 将json对象转成字典 -> 进行解码
    with open("hm.json", "r", encoding="utf-8") as f:
        # 获取文件中数据 -> 字典
        new_dict = json.load(f)
    
        # 查看类型
        print(type(new_dict))
        # 获取名字
        print(new_dict["name"])
        # 获取年龄
        print(new_dict["age"])
        # 获取学号
        print(new_dict["no"])
    
    
    # 写入
    import json
    
    # 定义一个字典
    my_dict = {
           "name": "老王", "age": 30, "no": "007"}
    
    # 将字典转成json -> 进行编码
    json_str = json.dumps(my_dict)
    
    # 打印json字符串
    print(type(json_str))
    
    # 把json数据写入到文件中
    with open("hm.json", "w", encoding="utf-8") as f:
        f.write(json_str)
    
    • xml文件
    // xml示例文件
    <list>
    <music title="再见理想">
       <format>盒带format>
       <year>1986year>
       <month>3month>
       <stars>10stars>
       <description>Beyond出品description>music><music title="光辉岁月">
       <format>盒带format>
       <year>1987year>
       <month>1month>
       <stars>9stars>
       <description>Beyond出品description>music>
        <music title="长城">
       <format>盒带format>
       <year>1992year>
       <month>8month>
       <stars>10stars>
       <description>Beyond出品description>music><music title="海阔天空">
       <format>盒带format>
       <year>1993year>
       <month>6month>
       <stars>10stars>
       <description>Beyond出品description>music>list>
    
    # 读取
    import xml.dom.minidom
    
    # 定义一个变量保存文件名
    file_name = "xml.xml"
    
    #打开xml文档
    domTree = xml.dom.minidom.parse(file_name)
    
    # 返回文档的根节点
    root = domTree.documentElement
    
    # 返回带有指定标签名的对象的集合(在集合中获取所有电影)
    musics = root.getElementsByTagName("music")
    
    # 打印每部电影的详细信息
    for music in musics:
    
       print("------音乐------")
       # 如果元素的属性为title
       if music.hasAttribute("title"):
          print("歌名: %s" % music.getAttribute("title"))
    
        # 格式
       type = music.getElementsByTagName("format")[0]
       print("-格式: %s" % type.childNodes[0].data)
       year = music.getElementsByTagName("year")[0]
       print("-年份: %s" % year.childNodes[0].data)
       month = music.getElementsByTagName("month")[0]
       print("-月份: %s" % month.childNodes[0].data)
       start = music.getElementsByTagName("stars")[0]
       print("-星数: %s" % start.childNodes[0].data)
       desc = music.getElementsByTagName("description")[0]
       print("-描述:%s" % desc.childNodes[0].data)
    
面向对象基础
  • 区分

    • 面向过程
      根据业务逻辑从上到下写代码
    • 面向对象(封装成类,可复用)
      将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程
      面向对象三大特性:封装、继承、多态
  • 类和对象

    • 定义
      • 类(抽象)
        类名、属性、方法
      • 实例对象
    • 自定义类
      class 类名:
      方法列表
    # class Hero:  # 经典类(旧式类)
    # class Hero():
    
    class Hero(object):  # 新式类
        def info(self):
            print("英雄各有见,何必问出处。")
    
    # object 是Python 里所有类的最顶级父类;
    # 类名 的命名规则按照"大驼峰命名法";
    # info 是一个实例方法,第一个参数一般是self,表示实例对象本身,当然了可以将self换为其它的名字,其作用是一个变量 这个变量指向了实例对象
    
    • 创建对象
      对象名1 = 类名()
      对象名2 = 类名()
      对象名3 = 类名()
    class Hero(object):  # 新式类
         # 1、定义实例方法
        def info(self):
            """当对象调用实例方法时,Python会自动将对象本身的引用做为参数,
                传递到实例方法的第一个参数self里"""
            print(self)
            print("self各不同,对象是出处。")
    
    # Hero这个类 2、实例化了一个对象  taidamier(泰达米尔)
    taidamier = Hero()
    
    # 3、对象调用实例方法info(),执行info()里的代码
    # . 表示选择属性或者方法
    taidamier.info()
    
    • 添加和获取对象的属性
    class Hero(object):
        def move(self):
            """实例方法"""
            print("正在前往事发地点...")
        def attack(self):
            print("发出了一招强力的普通攻击...")
    
    # 实例化了一个英雄对象 泰达米尔
    taidamier = Hero()
    
    # 给对象添加属性,以及对应的属性值
    taidamier.name = "泰达米尔"  # 姓名
    taidamier.hp = 2600  # 生命值
    taidamier.atk = 450  # 攻击力
    taidamier.armor = 200  # 护甲值
    
    # 通对.成员选择运算符,获取对象的属性值
    print("英雄 %s 的生命值 :%d" % (taidamier.name, taidamier.hp))
    print("英雄 %s 的攻击力 :%d" % (taidamier.name, taidamier.atk))
    print("英雄 %s 的护甲值 :%d" % (taidamier.name, taidamier.armor))
    
    # 通过.成员选择运算符,获取对象的实例方法
    taidamier.move()
    taidamier.attack()
    
    • 在方法内通过self获取对象属性
    class Hero(object):
        def move(self):
            print("正在前往事发地点...")
        def attack(self):
            print("发出了一招强力的普通攻击...")
    
        def info(self):
            """在类的实例方法中,通过self获取该对象的属性"""
            print("英雄 %s 的生命值 :%d" % (self.name, self.hp))
            print("英雄 %s 的攻击力 :%d" % (self.name, self.atk))
            print("英雄 %s 的护甲值 :%d" % (self.name, self.armor))
    
    # 实例化了一个英雄对象 泰达米尔
    taidamier = Hero()
    
    # 给对象添加属性,以及对应的属性值
    taidamier.name = "泰达米尔"  # 姓名
    taidamier.hp = 2600  # 生命值
    taidamier.atk = 450  # 攻击力
    taidamier.armor = 200  # 护甲值
    
    # 通过.成员选择运算符,获取对象的实例方法
    taidamier.info()  # 只需要调用实例方法info(),即可获取英雄的属性
    taidamier.move()
    taidamier.attack()
    
  • 魔法方法
    __开头,__结尾的方法,是python内置的方法,在特殊情况下被python执行(python可以监听到你使用自定义类创建一个对象)
    在自定义类中重写魔法方法

    • __init__()方法
      监听python使用其类创建对象完成,给这个对象设置属性
      在创建一个对象时默认被调用,不需要手动调用
    class Hero(object):
        """定义了一个英雄类"""
    
        def __init__(self, name, skill, hp, atk, armor):
            """ __init__() 方法,用来做变量初始化 或 赋值 操作"""
            self.name = name
            self.skill = skill
            self.hp = hp
            self.atk = atk
            self.armor = armor
    
        def move(self):
            """实例方法"""
            print("%s 正在前往事发地点..." % self.name)
        def attack(self):
            print("发出了一招强力的%s..." % self.skill)
        def info(self):
            print("英雄 %s 的生命值 :%d" % (self.name, self.hp))
            print("英雄 %s 的攻击力 :%d" % (self.name, self.atk))
            print("英雄 %s 的护甲值 :%d" % (self.name, self.armor))
    
    # 实例化英雄对象时,参数会传递到对象的__init__()方法里
    taidamier = Hero("泰达米尔", "旋风斩", 2600, 450, 200)
    gailun = Hero("盖伦", "大宝剑", 4200, 260, 400)
    
    # 不同对象的属性值单独保存
    print(id(taidamier.name))
    print(id(gailun.name))
    
    # 同一个类的不同对象,实例方法共享
    print(id(taidamier.move()))
    print(id(gailun.move()))
    
    • __new__()方法
      监听python使用其类创建对象,并返回对象 --> init
    class A(object):
        def __init__(self):
            print("这是 init 方法")
    
        def __new__(cls):
            print("这是 new 方法")
            return object.__new__(cls)
    
    A()
    
    # __new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供
    # __new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例
    # __init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值
    # 我们可以将类比作制造商,__new__方法就是前期的原材料购买环节,__init__方法就是在有原材料的基础上,加工,初始化商品环节
    
    • __str__()方法
      监听对象属性信息的变化,会返回一个字符串,不能添加参数,一般用于调试代码
      如果类中实现了__str__()方法,打印对象名,会输出__str__()方法的返回值
    class Hero(object):
        def __init__(self, name, skill, hp, atk, armor):
            self.name = name  
            self.skill = skill
            self.hp = hp 
            self.atk = atk
            self.armor = armor
    
        def move(self):
            print("%s 正在前往事发地点..." % self.name)
        def attack(self):
            """实例方法"""
            print("发出了一招强力的%s..." % self.skill)
    
        def __str__(self):
            return "英雄 <%s> 数据: 生命值 %d, 攻击力 %d, 护甲值 %d" % (self.name, self.hp, self.atk, self.armor)
    
    taidamier = Hero("泰达米尔", "旋风斩", 2600, 450, 200)
    gailun = Hero("盖伦", "大宝剑", 4200, 260, 400)
    
    # 如果没有__str__ 则默认打印对象在内存的地址。
    # 当类的实例化对象 拥有 __str__ 方法后,那么打印对象则打印 __str__ 的返回值。
    print(taidamier)
    print(gailun)
    
    • __del__()方法
      监听对象销毁后调用的方法
    class Hero(object):
    
        # 初始化方法,创建完对象后会自动被调用
        def __init__(self, name):
            print('__init__方法被调用')
            self.name = name
    
        # 当对象被删除时,会自动被调用
        def __del__(self):
            print("__del__方法被调用")
            print("%s 被 GM 干掉了..." % self.name)
    
    # 创建对象
    taidamier = Hero("泰达米尔")
    
    # 删除对象
    print("%d 被删除1次" % id(taidamier))
    del(taidamier)
    
    gailun = Hero("盖伦")
    gailun1 = gailun
    gailun2 = gailun
    
    print("%d 被删除1次" % id(gailun))
    del(gailun)
    
    print("%d 被删除1次" % id(gailun1))
    del(gailun1)
    
    print("%d 被删除1次" % id(gailun2))
    del(gailun2)
    
    • 内存回收机制(粗略)
      当使用del() 删除变量指向的对象时,则会减少对象的引用计数。如果对象的引用计数不为1,那么会让这个对象的引用计数减1,当对象的引用计数为0的时候,则对象才会被真正删除(内存被回收)
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3ZR9vzfA-1612875771802)(en-resource://database/1124:1)] @w=300h=400
    • 注意
      类内部获取 属性 和 实例方法,通过self获取;
      类外部获取 属性 和 实例方法,通过对象名获取。
  • 继承

    • 单继承
      只继承一个父类
    # 定义一个Master类
    class Master(object):
        def __init__(self):
            # 属性
            self.kongfu = "古法煎饼果子配方"
    
        # 实例方法
        def make_cake(self):
            print("按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
    
    # 定义Prentice类,继承Master
    class Prentice(Master):
        # 子类可以继承父类所有的属性和方法
        pass                
    
    # laoli = Master()
    # print(laoli.kongfu)
    # laoli.make_cake()
    
    damao = Prentice()  # 创建子类实例对象
    print(damao.kongfu) # 子类对象可以直接使用父类的属性
    damao.make_cake()   # 子类对象可以直接使用父类的方法
    
    • 多继承
      如果多个父类中有同名的 属性和方法,则默认使用第一个父类的属性和方法(根据类的魔法属性mro的顺序来查找)
    class Master(object):
        def __init__(self):
            self.kongfu = "古法煎饼果子配方"  
        def make_cake(self):                   
            print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
        def dayandai(self):
            print("师傅的大烟袋..")
    
    class School(object):
        def __init__(self):
            self.kongfu = "现代煎饼果子配方"
        def make_cake(self):
            print("[现代] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
        def xiaoyandai(self):
            print("学校的小烟袋..")
    
    class Prentice(Master, School):  # 多继承(Master在前)
        pass
    
    damao = Prentice()
    print(damao.kongfu) # 执行Master的属性
    damao.make_cake() # 执行Master的实例方法
    
    # 子类的魔法属性__mro__决定了属性和方法的查找顺序
    print(Prentice.__mro__)
    
    damao.dayandai() # 不重名不受影响
    damao.xiaoyandai()
    
    • 重写
      子类继承父类,做自己特有的事情
      子类和父类的方法名和属性名相同,则默认使用子类的
    • 子类调用父类同名属性和方法(已重写)
      父类类名.父类方法(self) --> self指定调用的对象
    class Master(object):
        def make_cake(self):                   
            print("按照 [古法] 制作了一份煎饼果子...")
    
    class School(object):
        def make_cake(self):
            print(" 按照 [现代] 制作了一份煎饼果子...")
    
    # 多继承,继承了多个父类
    class Prentice(School, Master):
        # 实例方法
        def make_cake(self):
            print("按照 [猫氏] 制作了一份煎饼果子...")
    
        # 调用父类方法格式:父类类名.父类方法(self)
        def make_old_cake(self):
            # 调用父类Master的实例方法
            Master.make_cake(self)
    
        def make_new_cake(self):
            # 调用父类School的实例方法
            School.make_cake(self)
    
    # 实例化对象,自动执行子类的__init__方法
    damao = Prentice()
    
    damao.make_cake() # 调用子类的方法(默认重写了父类的同名方法)
    
    damao.make_old_cake() # 进入实例方法去调用父类Master的方法
    
    damao.make_new_cake() # 进入实例方法去调用父类School的方法
    
    damao.make_cake() # 调用本类的实例方法
    
    • super()方法
      super()默认会调用第一个父类的方法(适用于单继承或者只想使用第一个父类方法的多继承)
    
    class Master(object):
        def make_cake(self):
            print("按照 [古法] 制作了一份煎饼果子...")
    class School(Master):
        def make_cake(self):
            print("按照 [现代] 制作了一份煎饼果子...")
            # 执行父类的实例方法 -->可以直接在子类一个方法里面调用父类
            super().make_cake()
    
    class Prentice(School, Master):
        def make_cake(self):
            print("按照 [猫氏] 制作了一份煎饼果子...")
    
        def make_all_cake(self):
            # 方式1. 指定执行父类的方法(代码臃肿)
            # School.make_cake(self)
            # Master.make_cake(self)
    
            # 方法2. super() 带参数版本,只支持新式类
            # super(Prentice, self).make_cake()
            # self.make_cake()
    
            # 方法3. super()的简化版,只支持新式类
            # 执行父类的 实例方法
            super().make_cake()
    
    damao = Prentice()
    damao.make_cake()
    damao.make_all_cake()
    
  • 私有属性和私有方法
    在属性和方法名前面加了2个下划线’__’,则表明该属性和方法是私有权限,否则为公有权限 -->类似java里的public&private
    1. 类的私有属性 和 私有方法,都不能通过对象直接访问,但是可以在本类内部访问;
    2. 类的私有属性 和 私有方法,都不会被子类继承,子类也无法访问;
    3. 私有属性 和 私有方法 往往用来处理类的内部事情,不通过对象处理,起到安全作用。

    class Master(object):
        def __init__(self):
            self.kongfu = "古法煎饼果子配方"
        def make_cake(self):          
            print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
    
    class School(object):
        def __init__(self):
            self.kongfu = "现代煎饼果子配方"
        def make_cake(self):
            print("[现代] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
    
    class Prentice(School, Master):
        def __init__(self):
            self.kongfu = "猫氏煎饼果子配方"
            # 私有属性,可以在类内部通过self调用,但不能通过对象访问
            self.__money = 10000  
    
        # 私有方法,可以在类内部通过self调用,但不能通过对象访问
        def __print_info(self):
            print(self.kongfu)
            print(self.__money)
    
        def make_cake(self):
            self.__init__()
            print("[猫氏] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
    
        def make_old_cake(self):
            Master.__init__(self)
            Master.make_cake(self)
    
        def make_new_cake(self):
            School.__init__(self)
            School.make_cake(self)
    
    class PrenticePrentice(Prentice):
        pass
    
    damao = Prentice()
    # 对象不能访问私有权限的属性和方法# print(damao.__money)
    # damao.__print_info()
    
    pp = PrenticePrentice()
    # 子类不能继承父类私有权限的属性和方法
    print(pp.__money)
    pp.__print_info()
    
    • 修改私有属性的值
      间接通过公有方法
    class Master(object):
        def __init__(self):
            self.kongfu = "古法煎饼果子配方"
        def make_cake(self):          
            print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
    
    class School(object):
        def __init__(self):
            self.kongfu = "现代煎饼果子配方"
        def make_cake(self):
            print("[现代] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
    
    class Prentice(School, Master):
        def __init__(self):
            self.kongfu = "猫氏煎饼果子配方"
            # 私有属性,可以在类内部通过self调用,但不能通过对象访问
            self.__money = 10000  
    
        # 现代软件开发中,通常会定义get_xxx()方法和set_xxx()方法来获取和修改私有属性值。
    
        # 返回私有属性的值
        def get_money(self):
            return self.__money
    
        # 接收参数,修改私有属性的值
        def set_money(self, num):
            self.__money = num
    
        def make_cake(self):
            self.__init__()
            print("[猫氏] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu)
    
        def make_old_cake(self):
            Master.__init__(self)
            Master.make_cake(self)
    
        def make_new_cake(self):
            School.__init__(self)
            School.make_cake(self)
    
    class PrenticePrentice(Prentice):
        pass
    
    damao = Prentice()
    # 对象不能访问私有权限的属性和方法
    # print(damao.__money)
    # damao.__print_info()
    
    # 可以通过访问公有方法set_money()来修改私有属性的值
    damao.set_money(100)
    
    # 可以通过访问公有方法get_money()来获取私有属性的值
    print(damao.get_money())
    
  • 多态
    定义时的类型和运行时的类型不一样;python中弱化类型(重点在于对象参数是否有指定的属性和方法,如果有就认定合适,而不关心对象的类型是否正确 --> “鸭子类型”)

class F1(object):
    def show(self):
        print('F1.show')

class S1(F1):
    def show(self):
        print('S1.show')

class S2(F1):
    def show(self):
        print('S2.show')

def Func(obj):  
    # python是弱类型,即无论传递过来的是什么,obj变量都能够指向它,这也就没有所谓的多态了(弱化了这个概念)
    print(obj.show())

s1_obj = S1()
Func(s1_obj)

s2_obj = S2()
Func(s2_obj)
  • 内存问题
    • 对象需要占用内存,且和对象属性地址不同
    • 对象的属性也要占用内存,且和对象的地址不同
    • 不同的对象,调用对象方法的地址相同(因为方法中有形参self,可以区分是哪个对象调用的)
    • python的小整数缓存池(-5~256之间) id相同
    • 字符串 元组 字典 列表 也有缓存池(小于2kb)
  • 类属性和实例属性
# 类属性就是类对象所拥有的属性
class People(object):
    name = 'Tom'  # 公有的类属性
    __age = 12  # 私有的类属性

p = People()

# 实例属性就是对象属性
class People(object):
    address = '山东'  # 类属性
    def __init__(self):
        self.name = 'xiaowang'  # 实例属性
        self.age = 20  # 实例属性

p = People()

# 若需要在类外修改类属性,必须通过类对象(Peole.name = 'xx')去引用然后进行修改。
# 如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性
  • 类中的方法
    • 实例方法
    • 类方法
    class People(object):
        country = 'china'
    
        #类方法,用classmethod来进行修饰    
        @classmethod
        def get_country(cls):
            return cls.country
    
        @classmethod
        def set_country(cls,country):
            cls.country = country
    
    p = People()
    print(p.get_country())    #可以用过实例对象引用
    print(People.get_country())    #可以通过类对象引用
    
    # 对类属性进行修改
    p.set_country('japan')   
    
    print(p.get_country())
    print(People.get_country())
    
    • 静态方法
    class People(object):
        country = 'china'
    
        #静态方法
        @staticmethod
        def get_country(): #没有默认形参
            return People.country
    
    p = People()
    # 通过对象访问静态方法
    p.get_contry()
    
    # 通过类访问静态方法
    print(People.get_country())
    
    • 总结
    - 实例方法(对象方法) -> 场景很多
        - 定义格式: def 实例方法名(self):
        - 调用格式: 对象名.实例方法名()
        - 使用场景: 在方法中需要self
    
    - 类方法-> 对私有类属性取值或者赋值
        - 定义格式: @classmethod
                    def 类方法名(cls):
        - 调用格式: 类名.类方法名() 或者 对象名.类方法名()
        - 使用场景: 在方法中需要cls(类名)
    
    - 静态方法 -> 一般不用
        - 定义格式: @staticmethod
                    def 静态方法名():
        - 调用格式: 类名.类方法名() 或者 对象名.类方法名()
        - 使用场景: 在方法中不需要self  也不需要cls
    
  • 单例模式(设计模式)–> 节约内存
    • 定义
      确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,单例模式是一种对象创建型模式
      单例模式:在程序中这个类创建出来的对象只有一个,也就是只占用一份内存;也**只会运行一次__init __()方法 **–>保证对象地址唯一,保证其对象的属性只会被赋值一次
# 实例化一个单例
class Singleton(object):
    __instance = None
    __is_first = True

    def __new__(cls, age, name):
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
        return cls.__instance

    def __init__(self, age, name):
        if self. __is_first:
            self.age = age
            self.name = name
            Singleton. __is_first = False

a = Singleton(18, "小明")
b = Singleton(28, "小明")

print(id(a))
print(id(b))

print(a.age)
print(b.age)

a.age = 19
print(b.age)
异常
  • 捕获异常
    • try…except
    try:
        执行可能发生异常的代码
    except (异常类型1,异常类型2,...:  #单个异常,多个异常,所有异常(except Exception:...)
        如果发生异常执行的代码
    
    • 获取异常信息描述
    try:
        执行可能发生异常的代码
    except (异常类型1,异常类型2,...as 临时变量:
        可以获得临时变量 #print("exceptions",e) 
    
    • try…exceprt…else
      else后跟未发生异常的代码
    • try…except…finally
      finally后跟必须要执行的代码
  • 异常的传递
    • try嵌套中
      try嵌套,那么如果里面的try没有捕获到这个异常,那么外面的try会接收到这个异常,然后进行处理,如果外边的try依然没有捕获到,那么再进行传递
    import time
    try:
        f = open('test.txt')
        try:
            while True:
                content = f.readline()
                if len(content) == 0:
                    break
                time.sleep(2)
                print(content)
        finally:
            f.close()
            print('关闭文件')
    except:
        print("没有这个文件")
    
    • 函数嵌套中
    def my_func1():
    try:
        print(num)
    except:
        print("异常")
    
    def my_func2():
     my_func1()
    
    def my_func3():
        my_func2()
    
    my_func3()
    
模块
  • 模块介绍
    变量(全局变量 局部变量 实例属性 类属性)–> 方法(实例方法 类方法 静态方法)–>模块–> 包–>工程(项目)
    • import
      引入格式:import 模块名
      使用格式:模块名.全局变量名;模块名.函数名;模块名.类名
    • from…import
      格式:from 模块名 import 全局变量 函数 类
      注意:和本模块名字冲突
      from 模块名 *:全部导入,使用时不需要写模块名
    • 关键词as–>别名
    • 关键词__all__
      如果一个模块中使用了__all__,列表中的字符串才可以在其他模块中使用;但其他模块必须是通过from…import * 方式导入的模块

    • 导入格式:包名.模块名 as 别名

你可能感兴趣的:(Python,python)