Python学习笔记

从A+B开始


#从键盘中输入两个整数并相加
a=input("请输入一个加数")
a=int(a)
b=input("请输入另一个加数")
b=int(b)
print(a+b)

#a=int(input("请输入一个加数"))
#b=int(input("请输入另一个加数"))

Python中的一些运算符


#python中的一些运算符
print(11//2) #整除运算
print(11%2)  #取余运算
print(2**3)  #2的3次方
print(9//-4) #一正一负向下取整

print('----------解包赋值------------')
a,b,c=20,30,40 #支持系列解包赋值
print(a,b,c)

print('---------交换两个变量的值-----------')
a,b=b,a
print(a,b)

print('--------------比较变量值或者标识-----------------')
a=10
b=10
print(a==b) #True 比较两个变量的value值
print(a is b) #True 比较两个变量的id标识

print('--------------比较数组值或者标识-----------------')
list1=[11,22,33,44]
list2=[11,22,33,44]
print(list1==list2) #True 比较两个数组的value值
print(list1 is list2) #False 比较两个数组的id标识
print(id(list1)) #输出数组地址值
print(id(list2))

print('---------------in  or  not in---------------------')
s='helloworld'
print('w' in s)
print('a' in s)

#优先级:算术运算(幂运算>乘除取余整除>加减)-> 位运算 -> 比较运算 -> 布尔运算 -> 赋值运算

if语句


#if语句用法
money=1000 #余额
s=int(input('请输入取款金额'))
#判断余额是否充足
if money>s:
    money-=s
    print('取款成功,余额为:',money)
elif money<s:
    print('余额不足')
else:
    print('余额为0')

#多分支结构关键词 elif

#条件表达式
num_a=int(input('请输入一个数:'))
num_b=int(input('请输入另一个数:'))

'''if num_a>num_b:
    print(num_a,'大于',num_b)
else :
    print(num_a,'小于等于',num_b)
'''
#等价于
print(str(num_a)+'大于'+str(num_b) if num_a>num_b else str(num_a)+'小于等于'+str(num_b))

pass的用法


#pass语句:什么都不做,只是占位符,用到需要写语句的地方

num_a=int(input('请输入一个数:'))
num_b=int(input('请输入另一个数:'))

if num_a>num_b:
    pass
else :
    print(num_a,'小于等于',num_b)

range函数的使用


# range函数
#   用于生成一个整数序列
#创建range对象的三种方式
#1.  range(stop) 创建一个[0,stop)之间的整数序列,步长为1
#2.  range(start,stop)  创建一个[start,stop)之间的整数序列,步长为1
#3.  range(start,stop,step)  创建一个[start,stop)之间的整数序列,步长为step

print('---------------range(stop)------------------')
r1=range(10)
print(r1)   #range(0, 10)
print(list(r1))    #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print('-----------------range(start,stop)--------------------')
r2=range(1,10)
print(r2)   #range(1, 10)
print(list(r2))   #[1, 2, 3, 4, 5, 6, 7, 8, 9]

print('------------------range(start,stop,step)----------------------')
r3=range(1,10,2)
print(r3)   #range(1, 10, 2)
print(list(r3))    #[1, 3, 5, 7, 9]

while循环和for-in循环


#while循环
a=1
while a<10:
    #执行条件执行体
    print(a)
    a+=1

#1到100之间的偶数和
sum=0
a=1
while a<=100:
    if a%2==0:
        sum+=a
    a+=1
print('1到100的偶数和为',sum)


#for-in循环

#依次将字母取出
for item in 'python':
    print(item)
for i in range(10):
    print(i)

#如果循环体中不需要使用到自定义变量,可以将自定义变量写为“_”
for _ in range(5):
    print('人生苦短,我用python')

#计算1到100之间的偶数和
sum=0
for item in range(101):
    if not item%2:
        sum+=item
print('1到100之间的偶数和',sum)

#输出100到999之间的水仙花数
for item in range(100,1000):
    ge=item%10
    shi=item//10%10
    bai=item//100
    if item==ge**3+shi**3+bai**3:
        print(item)

#输出九九乘法表
for i in range(1,10):
    for j in range(1,i+1):
        print(i,'*',j,'=',i*j,end='\t')
    print()  #换行


#输入三次密码
for item in range(3):
    pwd=input('请输入密码:')
    if pwd=='8888':
        print('密码正确')
        break
    else:
        print('密码不正确')
else:
    print('对不起,三次密码均输入错误')


列表list


#列表的创建(数据类型可以混合)
#1. 使用中括号
lst=['大圣','娟子姐']
#2. 调用内置函数list
lst2=list(['大圣','娟子姐'])
print(lst[0]) #大圣 获取第一个元素
print(lst[-2]) #大圣 从最后一个往前,最后一个元素索引为'-1',依次递减

#获取index索引
lst3=['hello','windows',98]
print('获取hello的索引:',lst3.index('hello')) #如果有相同元素返回第一个出现的元素的索引
print('获取hello的索引:',lst3.index('hello',0,3)) #在指定范围内查找,[0,3)


#列表元素的查询操作
#获取列表中的多个元素(切片操作)
#语法格式:列表名[start : stop : step] step默认为1
lst4=[10,20,30,40,50,60,70,80]
print(lst4[1:6:1])  #[20, 30, 40, 50, 60]
lst5=lst4[1:6:1]  #新的列表,原列表的拷贝
print('----------步长为负数的情况----------')
print(lst4[::-1]) #逆序整个列表



#列表元素的增加操作
#append() 在列表末尾添加一个元素
#extend() 在列表末尾至少添加一个元素
#insert() 在列表的任一位置添加一个元素
#切片 在列表的任意位置至少添加一个元素

#append() 在列表末尾添加一个元素
lst6=[10,20,30]
print('添加元素之前:',lst6)
lst6.append(40)
print('添加元素之后:',lst6)  #同一个列表,ID相同

#extend() 在列表末尾至少添加一个元素
lst7=[50,60]
#lst6.append(lst7) 将lst7作为一个元素添加到列表末尾
lst6.extend(lst7)
print('添加元素之后:',lst6)  #添加元素之后: [10, 20, 30, 40, 50, 60]

#insert() 在列表的任一位置添加一个元素
lst6.insert(6,70)  #insert(index,value)
print('添加元素之后:',lst6)  #添加元素之后: [10, 20, 30, 40, 50, 60, 70]

#切片 在列表的任意位置至少添加一个元素
lst8=[20,30,40]
lst6[1:]=lst8  #把索引从1开始的元素替换
print('添加元素之后:',lst6)  #添加元素之后: [10, 20, 30, 40]



#列表元素的删除操作
#remove() 一次删除一个元素
#         重复元素只删除第一个
#         元素不存在抛出ValueError
#pop()    删除一个索引位置上的元素
#         指定索引不存在抛出ValueError
#         不指定索引,删除列表中最后一个元素
#切片      一次至少删除一个元素
#clear()  清空列表
#del      删除列表

#remove()
lst9=[10,20,30,40,50,60,30]
print('删除元素之前:',lst9)  #删除元素之前: [10, 20, 30, 40, 50, 60, 30]
lst9.remove(30)
print('删除元素之后:',lst9)  #删除元素之后: [10, 20, 40, 50, 60, 30]

#pop()
lst9.pop(1)
print('删除元素之后:',lst9)  #删除元素之后: [10, 40, 50, 60, 30]
lst9.pop()
print('删除元素之后:',lst9)  #删除元素之后: [10, 40, 50, 60]

#切片操作
lst9[1:3]=[]  #切片替换
print('删除元素之后:',lst9)  #删除元素之后: [10, 60]

#clear()
lst9.clear()
print('删除元素之后:',lst9)  #删除元素之后: []

#del
del lst9


#列表的排序操作
lst10=[10,20,23,435,22,34]
print('排序前的列表:',lst10)  #排序前的列表: [10, 20, 23, 435, 22, 34]
lst10.sort()  #默认是升序,在原列表的基础上进行排序
print('排序后的列表:',lst10)  #排序后的列表: [10, 20, 22, 23, 34, 435]
lst10.sort(reverse=True)  #降序排序,在原列表的基础上进行排序
print('排序后的列表:',lst10)  #排序后的列表: [435, 34, 23, 22, 20, 10]

new_list=sorted(lst10)  #产生一个新的列表对象
print('排序后的列表:',new_list)
new_list=sorted(lst10,reverse=True)  #降序排序
print('排序后的列表:',new_list)


#列表生成式
lst11=[i for i in range(1,10)]
print('生成的列表',lst11)  #生成的列表 [1, 2, 3, 4, 5, 6, 7, 8, 9]
lst12=[i*i for i in range(1,10)]
print('生成的列表',lst12)  #生成的列表 [1, 4, 9, 16, 25, 36, 49, 64, 81]

字典dictionary


# 字典:字典是python内置的数据结构之一,与列表一样是个可变序列
# 以键值对的方式存储数据,字典是一个无序的序列
# 键不允许重复,值可以重复,若出现键重复则值覆盖


# 字典的创建
# 最常用的方式:使用花括号
scores={'张三':100,'李四':90,'王五':85}
print(scores)  #{'张三': 100, '李四': 90, '王五': 85}
print(type(scores))  #<class 'dict'>
#使用内置函数dict()
student=dict(name='jack',age=20)
print(student)  #{'name': 'jack', 'age': 20}


# 字典的元素获取
# []如果字典中不存在指定的key,抛出keyError异常
# get()方法取值,如果字典中不存在指定的key,并不会抛出KeyError而是返回None,可以通过参数设置默认的value,以便指定的key不存在时返回
print(scores['张三'])  #100
print(scores.get('张三'))  #100
print(scores.get('陈六'))  #None
print(scores.get('陈六',0))  #0,查找'陈六'所对的value不存在时,输出默认值


# 判断元素是否在字典中存在
print('张三' in scores) #True

# 字典元素的删除及增加
del scores['张三']  #删除字典元素
print(scores)  #{'李四': 90, '王五': 85}
scores['张三']=100  #增加字典元素
print(scores)  #{'李四': 90, '王五': 85, '张三': 100}
scores.clear()  #清空字典元素
print(scores)  #{}


# 获得字典视图的三个方法
# keys() 获得字典中所有的key
# values() 获得字典中所有的value
# items() 获得字典中所有的对key,value对

scores={'张三':100,'李四':90,'王五':85}
keys=scores.keys()
print(keys)  #dict_keys(['张三', '李四', '王五'])
print(type(keys))  #<class 'dict_keys'>
print(list(keys))  #['张三', '李四', '王五'] , 将所有key组成的视图转化为列表

values=scores.values()
print(values)  #dict_values([100, 90, 85])
print(type(values))  #<class 'dict_values'>
print(list(values))  #[100, 90, 85] , 将所有values组成的视图转化为列表

items=scores.items()
print(items)  #dict_items([('张三', 100), ('李四', 90), ('王五', 85)])
print(type(items))  #<class 'dict_items'>
print(list(items))  #[('张三', 100), ('李四', 90), ('王五', 85)] , 将键值对转化为元组


# 字典元素的遍历
for item in scores:
    print(item,scores.get(item))


# 字典生成式
# 内置函数zip()
# 用于将可迭代的对象作为参数,将对象中对应的元素打包成一个元组,然后返回由这些元组组成的列表
items=['fruits','books','others']
prices=[96,78,85]
d={name:p for name,p in zip(items,prices)}
print(d)  #{'fruits': 96, 'books': 78, 'others': 85}
d={name.upper():p for name,p in zip(items,prices)}
print(d)  #{'FRUITS': 96, 'BOOKS': 78, 'OTHERS': 85} , 转成大写

d=dict(zip(items,prices))
print(d)  #{'fruits': 96, 'books': 78, 'others': 85}

元组tuple


# 元组:python内置的数据结构之一,是一个不可变序列 ,使用()
# 不可变序列与可变序列
# 不可变序列:字符串、元组 (没有增、删、改的操作)
# 可变序列:列表、字典 (可以对序列执行增、删、改操作,对象地址不发生更改)

# 为什么要将元组设计成不可变序列
# 在多任务环境下,同时操作对象时不需要加锁
# 因此,在程序中尽量使用不可变序列
# 注意事项:元组中存储的是对象的引用
#     a)如果元组中对象本身不可对象,则不能再引用其它对象
#     b)如果元组中的对象是可变对象,则可变对象的引用不允许改变,但数据可以改变


# 元组的创建方式
# 直接小括号 (小括号可以省略)
t=('python','hello',90)
print(t)
# 使用内置函数tuple()
t=tuple(('python','hello',90))
print(t)
# 只包含一个元组的元素需要使用逗号和小括号
t=(10,)
print(t)


# 元组的遍历
# 使用索引
print(t[0])
# 使用for-in
for item in t:
    print(item)

集合set


# 集合是python语言提供的内置数据结构
# 与列表、字典一样属于可变类型的序列,集合是没有value的字典


# 集合的创建
# 直接使用{}
s={'python','hello',90}
s={1,1,2,3,3,5}  #{1, 2, 3, 5} ,集合中的元素不允许重复
print(s)
# 使用内置函数set()
s=set(range(6))
print(s)  #{0, 1, 2, 3, 4, 5}
print(set([0,1,2,3]))  #{0, 1, 2, 3} ,将列表元素转换成集合元素
print(set((0,1,2,3)))  #{0, 1, 2, 3} ,将元组元素转换成集合元素


# 集合的判断操作
print('-------------集合的判断操作------------------')
# 使用in或not in
s={10,20,30,40}
print(10 in s)  #True


# 集合元素的新增操作
print('-------------集合元素的新增操作------------------')
# 调用add()方法,一次添加一个元素
# 调用update()方法,一次至少添加一个元素

s.add(50)
print(s)  #{40, 10, 50, 20, 30} ,集合无序
s.update([60,70,80])
print(s)  #{70, 40, 10, 80, 50, 20, 60, 30}


# 集合元素的删除操作
print('-------------集合元素的删除操作------------------')
# 调用remove()方法,一次删除一个指定元素,如果指定的元素不存在抛出KeyError
# 调用discard()方法,一次删除一个指定元素,如果指定的元素不存在不抛异常
# 调用pop()方法,一次只删除一个任意元素
# 调用clear()方法,清空集合

s.remove(80)
print(s)  #{70, 40, 10, 50, 20, 60, 30}
s.discard(70)
print(s)  #{40, 10, 50, 20, 60, 30}
s.pop()
print(s)  #{10, 50, 20, 60, 30}
s.clear()
print(s)  #set()


# 集合之间的关系
print('-------------集合之间的关系------------------')
# 两个集合是否相等
#     ·可以使用运算符==或!=进行判断 —个集合是否是另一个集合的子集
# 一个集合是否是另一个集合的子集
#     ·可以调用方法issubset进行判断
# 一个集合是否是另一个集合的超集
#     ·可以调用方法issuperset进行判断
# 两个集合是否没有交集
#     ·可以调用方法isdisjoint进行判断

s1={10,20,30,40}
s2={30,40,20,10}
print(s1==s2)  #True
s3={10,20}
print(s3.issubset(s1))  #True
print(s2.issuperset(s3))  #True
print(s2.isdisjoint(s3))  #False ,有交集为False


# 集合的数学操作
print('-------------集合的数学操作------------------')
# 交集
s1={10,20,30,40}
s2={20,30,40,50}
print(s1.intersection(s2))  #{40, 20, 30}
print(s1 & s2)  #{40, 20, 30}
# 并集
print(s1.union(s2))  #{40, 10, 50, 20, 30}
print(s1 | s2)  #{40, 10, 50, 20, 30}
# 差集
print(s1.difference(s2))  #{10}
print(s1 - s2)  #{10}
# 对称差集
print(s1.symmetric_difference(s2))  #{10, 50}
print(s1 ^ s2)  #{10, 50}


#集合生成式
print('-------------集合生成式------------------')
s={i for i in range(6)}
print(s)  #{0, 1, 2, 3, 4, 5}

字符串string


# 字符串:在Python中字符串是基本数据类型,是一个不可变的字符序列
# 字符串驻留机制:
#      仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,
#      Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串时,
#      不会开辟新空间,而是把该字符串的地址赋给新创建的变量

# 驻留机制的几种情况(交互模式) (在cmd中运行python)
#    1)字符串的长度为O或1时
#    2)符合标识符的字符串
#    3)字符串只在编译时进行驻留,而非运行时
#    4)[-5.256]之间的整数数字

# 字符串的创建
a='python'
b="python"
c='''python'''
print(a,b,c,id(a),id(b),id(c))  #python python python 1932068462320 1932068462320 1932068462320


# 字符串的查询操作
print('-----------字符串的查询操作---------------')
# index():查找子串substr第一次出现的位置,如果查找的子串不存在时,则抛出ValueError
# rindex():查找子串substr最后一次出现的位置,如果查找的子串不存在时,则抛出ValueError
# find():查找子串substr第一次出现的位置,如果查找的子串不存在时,则返回-1
# rfind():查找子串substr最后一次出现的位置,如果查找的子串不存在时,则返回-1

s='hello,hello'
print(s.index('lo'))  #3
print(s.rindex('lo'))  #9
print(s.find('lo'))  #3
print(s.rfind('lo'))  #9


# 字符串的大小写转换操作
print('-----------字符串的大小写转换操作---------------')
# upper():把字符串中所有字符都转成大写字母
# lower():把字符串中所有字符都转成小写字母
# swapcase():把字符串中所有大写字母转成小写字母,把所有小写字母都转成大写字母
# capitalize():把第一个字符转换为大写,把其余字符转换为小写
# title():把每个单词的第一个字符转换为大写,把每个单词的剩余字符转换为小写
s='hello,python'
a=s.upper()
print(a)  #HELLO,PYTHON ,产生新字符串对象
b=s.lower()
print(b)  #hello,python ,产生新字符串对象(包括不发生改变)
c=s.swapcase()
print(c)  #HELLO,PYTHON
d=s.capitalize()
print(d)  #Hello,python
e=s.title()
print(e)  #Hello,Python


# 字符串内容对其操作
print('-----------字符串内容对其操作---------------')
# center():居中对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
# ljust():左对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
# rjust():右对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
# zfill():右对齐,左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,如果指定的宽度小于等于字符串的长度,返回字符串本身

s='hello,python'
print(s.center(20,'*'))   # ****hello,python****
print(s.ljust(20,'*'))    # hello,python********
print(s.rjust(20,'*'))    # ********hello,python
print(s.zfill(20))        # 00000000hello,python
print('-1234'.zfill(10))  # -000001234 ,字符串首位为+/-时,会把+/-置顶


# 字符串的劈分操作
print('-----------字符串的劈分操作---------------')
# split():从字符串的左边开始劈分,默认的劈分字符是空格字符串,返回的值都是一个列表
#         以通过参数sep指定劈分字符串是的劈分符
#         通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大次劈分之后,剩余的子串会单独做为一部分
# rsplit():从字符串的右边开始劈分,默认的劈分字符是空格字符串,返回的值都是一个列表
#          以通过参数sep指定劈分字符串是的劈分符
#          通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大次劈分之后,剩余的子串会单独做为一部分

s='hello world python'
print(s.split())  #['hello', 'world', 'python']
s1='hello|world|python'
print(s1.split(sep='|'))  #['hello', 'world', 'python']
print(s1.split(sep='|',maxsplit=1))  #['hello', 'world|python']
print(s1.rsplit(sep='|',maxsplit=1))  #['hello|world', 'python']


# 判断字符串操作的方法
print('-----------判断字符串操作的方法---------------')
# isidentifier():判断指定的字符串是不是合法的标识符
# isspace():判断指定的字符串是否全部由空白字符组成(回车、换行,水平制表符)
# isalpha():判断指定的字符串是否全部由字母组成
# isdecimal():判断指定字符串是否全部由十进制的数字组成
# isnumeric():判断指定的字符串是否全部由数字组成
# isalnum():判断指定字符串是否全部由字母和数字组成

s='hello,world'
print(s.isidentifier())  #False
print('张三_123'.isidentifier())  #True
print('张三'.isalpha())  #True


# 字符串的替换与合并
print('-----------字符串的替换与合并---------------')
# 字符串替换replace():第1个参数指定被替换的子串,第2个参数指定替换子串的字符串,
#                   该方法返回替换后得到的字符串,替换前的字符串不发生变化,
#                   调用该方法时可以通过第3个参数指定最大替换次数
# 字符串合并join():将列表或元组中的字符串合并成一个字符串

s='hello,python'
print(s.replace('python','java'))  #hello,java
s1='hello,python,python,python'
print(s1.replace('python','java',2))  #hello,java,java,python

lst=['hello','java','python']
print('|'.join(lst))  #hello|java|python
print(' '.join(lst))  #hello java python
print('*'.join('python'))  #p*y*t*h*o*n

print(ord('a'),ord('邵'))   #得到原始值 97 37045
print(chr(97),chr(37045))   #得到原始值对应的字符 a 邵


# 字符串的切片操作([start:end:step])
print('-----------字符串的切片操作---------------')
s='hello,python'
s1=s[:5]
s2=s[6:]
print(s1,s2)  #hello python


# 格式化字符串
print('-----------格式化字符串---------------')
# %做占位符: %s 代表字符串,%i 或 %d 代表整数,%f 代表浮点数
# {}做占位符: {0}、{1}、{2}
# f-string

name='张三'
age=20
print('我叫%s,今年%d岁' % (name,age))  #我叫张三,今年20岁
print('我叫{0},今年{1}岁'.format (name,age))  #我叫张三,今年20岁
print(f'我叫{name},今年{age}岁')  #我叫张三,今年20岁

print('%5d' % age)  #   20 ,'5'表示宽度
print('%.3f' % 3.1415926)  #3.142 ,.3表示小数位数
print('{0:.3}'.format(3.1415826))  #3.14 ,.3表示有效位数


# 字符串的编码转换
print('-----------字符串的编码转换---------------')
# 编码:将字符串转换为二进制数据(bytes)
# 解码:将bytes类型的数据转换成字符串类型

#编码
s='天涯共此时'
print(s.encode(encoding='GBK'))  #b'\xcc\xec\xd1\xc4\xb9\xb2\xb4\xcb\xca\xb1' , 一个中文占两个字节
print(s.encode(encoding='UTF-8'))  #b'\xe5\xa4\xa9\xe6\xb6\xaf\xe5\x85\xb1\xe6\xad\xa4\xe6\x97\xb6' ,一个中文占三个字节

#解码
byte=s.encode(encoding='GBK')
print(byte.decode(encoding='GBK'))  #天涯共此时

函数function


# 函数的创建
# def 函数名([输入参数]) :
# 函数体
# [return xxx]

# a+b创建
def calc(a, b):
    c = a+b
    return c
# 函数调用
result = calc(10, 20)
print(result)  #30

res = calc(a=20, b=10)  #传递方式不同 =左边为关键字参数
print(result)


# 函数调用参数传递的内存分析(值传递和地址传递)
def fun(arg1, arg2):
    print('arg1=', arg1)  #arg1= 11
    print('arg2=', arg2)  #arg2= [11, 22, 33]
    arg1 = 100
    arg2.append(10)
    print('arg1=', arg1)  #arg1= 100
    print('arg2=', arg2)  #arg2= [11, 22, 33, 10]

n1 = 11
n2 = [11, 22, 33]
print(n1)
print(n2)
print('--------------------------------')
fun(n1, n2)
print(n1)  #11 , 没有被修改
print(n2)  #[11, 22, 33, 10] , 被修改

'''在函数调用过程中,进行参数的传递
   如果是不可变对象,在函数体的修改不会影响实参的值,arg1的修改为100,不会影响n1的值
   如果是可变对象,在函数体的的修改会影响到实参的值,arg2的修改append(10),会影响到n2的值
'''


# 函数的返回值
# 函数返回多个值时,结果为元组
def fun(num):
    odd=[]  #存奇数
    even=[]  #存偶数
    for i in num :
        if i%2:
            odd.append(i)
        else:
            even.append(i)
    return odd,even
print(fun([10,29,34,23,44,53,55]))  #([29, 23, 53, 55], [10, 34, 44])

'''函数的返回值
    (1)如果函数没有返回值【函数执行完毕之后,不需要给调用处提供数据】,return可以省略不写
    (2)函数的返回值,如果是1个,直接返回类型
    (3)函数的返回值,如果是多个,返回的结果为元组
'''

# 可变的位置参数和关键词参数(只能定义一个)
# 个数可变的位置参数:
#      定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数
#      使用*定义个数可变的位置形参
#      结果为一个元组
# 个数可变的关键词参数:
#      定义函数时,无法事先确定传递的关键字实参的个数时,使用可变的关键字形参
#      使用**定义个数可变的关键字形参
#      结果为一个字典

# 个数可变的位置参数
def fun(*args):
    print(args)
fun(10)  #(10,)
fun(10,20,30)  #(10, 20, 30)

# 个数可变的关键词参数
def fun(**args):
    print(args)
fun(a=10)  #{'a': 10}
fun(a=10,b=20,c=30)  #{'a': 10, 'b': 20, 'c': 30}

# 在一个函数的定义过程中,既有个数可变的关键字形参,也有个数可变的位置形参,要求个数可变的位置形参,放在个数可变的关键字之前
'''def fun(*arg1,**arg2):
    pass
'''


# 函数调用
print('------------函数调用-----------------')
def fun(a,b,c):
    print('a=',a)
    print('b=',b)
    print('c=',c)

lst=[11,22,33]
fun(*lst)  #在函数调用时,将列表中的每个元素都转换为位置实参传入(一定要加*)
dic={'a':11,'b':22,'c':33}
fun(**dic)  #在函数调用时,将列表中的每个元素都转换为关键字实参传入(一定要加**)

# 位置传递和关键字传递
def fun(a,b,*,c):
    print('a=',a)
    print('b=',b)
    print('c=',c)
fun(10,20,c=30)  # *之后的元素必须使用关键字传递

# 函数内部定义变量为局部变量,局部变量使用global定义就变成了全局变量


# 递归函数
# 阶乘函数
def fun(n):
    if n==1:
        return 1
    else:
        return n*fun(n-1)

print(fun(6))  #720

# 斐波那契数列
def fib(n):
    if n==1:
        return 1
    elif n==2:
        return 2
    else:
        return fib(n-1)+fib(n-2)

print(fib(6))  #13

for i in range(1,7):  #输出1到6的斐波那契数列
    print(fib(i))
    

异常


# try-except结构
try:
    n1 = int(input('请输入一个整数:'))
    n2 = int(input('请输入另一个整数:'))
    result = n1/n2
    print('结果为:', result)
except ZeroDivisionError:
    print('除数不能为0哦!')
except ValueError:
    print('只能输入整数')
print('程序结束')


# try-except-else结构
try:
    n1 = int(input('请输入一个整数:'))
    n2 = int(input('请输入另一个整数:'))
    result = n1/n2
except BaseException as e:
    print('出错了')
    print(e)
else:
    print('结果为:', result)


# try-except-else-finally结构
try:
    n1 = int(input('请输入一个整数:'))
    n2 = int(input('请输入另一个整数:'))
    result = n1/n2
except BaseException as e:
    print('出错了')
    print(e)
else:
    print('结果为:', result)
finally:
    pass
    # 此处为无论是否产生异常,总会被执行的代码

print('程序结束')


'''常见的异常:
    ZeroDivisionError:除(或取模)零(所有数据类型)
    IndexError:序列中没有此索引(index)
    KeyError:映射中没有这个键
    NameError:未声明/初始化对象(没有属性)
    SyntaxError:Python语法错误
    ValueError:传入无效的参数
'''


# traceback模块的使用(将异常信息存储到日志文件里:log日志)
import traceback
try:
    print('-----------------------------')
    print(1/0)
except:
    traceback.print_exc()

类class


# 类与对象
class Student:   # Student为类的名称(类名)由一个或多个单词组成,每个单词的首字母大写,其余小写
    pass

# Python中一切皆对象Student是对象吗?内存有开空间吗?
print(id(Student))   # 1639014241264
print(type(Student))  # <class 'type'
print(Student)  # <class '_main__.Student'>

# 类属性:类中方法外的变量称为类属性,被该类的所有对象所共享
# 类方法:使用@classmethod修饰的方法,使用类名直接访问的方法
# 静态方法:使用@staticmethod修饰的主法,使用类名直接访问的方法
# 类方法是需要使用类属性,与具体示例无关的方法(不需要使用self属性),类方法使用类名调用
# 实例方法是具体实例的操作方法,需要使用self的属性,实例方法只能创建实例,使用实例调用
# 静态方法是与类和具体实例都无关的方法,不需要使用类属性和实例属性,使用类名或对象都可以调用


class Student:
    native_place='吉林'  # 直接写在类里面的变量,称为类属性
    # 初始化方法
    def __init__(self,name,age):   # name, age为实例属性
        self.name = name
        self.age = age
    # 实例方法
    def info(self):  # 实例方法一般第一个参数为self,及实例对象
        print('我的名字叫:',self.name,'年龄是:',self.age)
    # 类方法
    # 有时候,有些属性和方法是和类有关的,和具体某个对象无关,此时便可以使用类属性和类方法
    # 类属性直接写在类中,类方法需要加上装饰器@classmethod
    @classmethod
    def cm(cls):   # cls代表class,即默认参数为class
        print('类方法')
    # 静态方法
    # 当类中有一个操作和类以及具体的实例都无关时(即不需要用到类属性以及实例属性时)便可以声明方法为静态方法,
    # 静态方法使用装饰器@staticmethod,参数中不需要self或cls。
    @staticmethod
    def sm() :
        print('静态方法')


# 创建Student类的对象
stu1 = Student('张三',20)
stu1.info()  # 我的名字叫: 张三 年龄是: 20  (对象.方法名)
Student.info(stu1)  # 我的名字叫: 张三 年龄是: 20  (类.方法名)
print(stu1.name,stu1.age)  # 张三 20

# 类属性的使用方式
print('-----------类属性的使用方式-----------------')
print(Student.native_place)  #吉林

# 类方法的使用方法
print('-----------类方法的使用方法-----------------')
print(Student.cm())

# 静态方法的使用方法
print('-----------静态方法的使用方法-----------------')
print(Student.sm())


# python是动态语言,在创建对象之后,可以动态绑定属性和方法
print('-------------python的动态绑定------------------')
def show():
    print('我是一个函数')

stu2=Student('Jack',20)
stu2.gender='男'  # 动态绑定性别,只有stu2这个实例有gender属性
print(stu2.name,stu2.age,stu2.gender)  # Jack 20 男
stu2.show=show  # 动态绑定函数
stu2.show()  # 我是一个函数

面向对象 Object Oriented


# 面向对象的三大特征
# 封装:提高程序的安全性
#       ·将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。
#        这样,无需关心方法内部的具体实现细节,从而隔离了复杂度。
#       ·在Python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个'_'。
# 继承:提高代码的复用性
# 多态:提高程序的可扩展性和可维护性

# object类是所有类的父类,因此所有类都有object类的属性和方法。
# 内置函数dir()可以查看指定对象所有属性
# object有一个_str_()方法,用于返回一个对于“对象的描述”,对应于内置函数str()经常用于print()方法,
# 帮我们查看对象的信息,所以我们经常会对_str_()进行重写


# 封装
class Student:
    def __init__(self, age):
        self.__age = age

    def get_age(self):
        return self.__age

    def set_age(self, age):
        if 0 <= age <= 120:
            self.__age = age
        else:
            self.__age = 18

stu1 = Student(150)
stu2 = Student(30)
print(stu1.get_age())
print(stu2.get_age())
# print(stu1.__age)  报错
print(dir(stu1))  # 获得被修改的属性名 '_Student__age'
print(stu1._Student__age)  # 150



# 继承
class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def info(self):
        print('姓名:{0},年龄{1}'.format(self.name, self.age))

# 定义子类
class Student(Person):
    def __init__(self, name, age, score):
        super().__init__(name, age)  # super()代表父类的
        self.score = score

# 测试
stu = Student('Jack', 20, 90)
stu.info()



# 方法重写
class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def info(self):
        print('姓名:{0},年龄{1}'.format(self.name, self.age))

class Student(Person):
    def __init__(self, name, age, score):
        super().__init__(name, age)  # super()代表父类的
        self.score = score
    def info(self):
        super().info()  # 调用父类的info()函数
        print('学号为:{0}'.format(self.score))

# 测试
stu = Student('Jack', 20, 90)
stu.info()   # 姓名:Jack,年龄20
             # 学号为:90



# 重写__str__()方法
class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
       return  '姓名:{0},年龄{1}'.format(self.name, self.age)  # 用return

person1 = Person('张三',20)
print(person1)  # 姓名:张三,年龄20 ,默认调用__str__()方法



# 多态
class Animal(object):
    def eat(self):
        print('动物要吃东西')

class Dog(Animal):
    def eat(self):
        print('狗吃肉')

class Cat(Animal):
    def eat(self):
        print('猫吃鱼')

class Person(object) :
    def eat(self):
     print('人吃五谷杂粮')

def fun(animal):
    animal.eat()

fun(Dog())  # 狗吃肉
fun(Cat())  # 猫吃鱼
fun(Person())  #人吃五谷杂粮



# 特殊方法和特殊属性
print('---------------特殊方法和特殊属性-------------------')
# 特殊属性: __dict__ :获得类对象或实例对象所绑定的所有属性和方法的字典
# 特殊方法: __len__() :通过重写_len_()方法,让内置函数len()的参数可以是自定义类型
#          __add__() :通过重写__add__()方法,可使用自定义对象具有“+”功能
#          __new__() :用于创建对象
#          __init__() :对创建的对象进行初始化


# 特殊属性
print('---------------特殊属性-------------------')
class A:
    pass
class B:
    pass
class C(A,B):
    def __init__(self, name, age):
        self.name = name
        self.age = age

x=C('Jack',20)
print(x.__dict__)  # {'name': 'Jack', 'age': 20} ,实例对象的属性字典
print(C.__dict__)  # {'__module__': '__main__', '__init__': <function C.__init__ at 0x000001AED3C77520>, '__doc__': None}
print(x.__class__)  # <class '__main__.C'> ,输出对象所属的类
print(C.__bases__)  # (<class '__main__.A'>, <class '__main__.B'>) ,输出父类类型的元素
print(C.__mro__)  # (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>) ,类的层次结构
print(A.__subclasses__())  # [<class '__main__.C'>] ,输出子类(子类的列表)


# 特殊方法
print('---------------特殊方法------------------')
class Student:
    def __init__(self, name):
        print('__init__()被调用执行了,self的id值为{0}'.format(id(self)))
        self.name = name
    def __add__(self, other):
        return self.name + other.name
    def __len__(self):
        return len(self.name)
    def __new__(cls, *args, **kwargs):
        print('__new__()被调用执行了,cls的id值为{0}'.format(id(cls)))
        obj = super().__new__(cls)
        print('创建的对象的id为{0}'.format(id(obj)))
        return obj

print('object这个类对象的id为:{0}'.format(id(object)))
print('Student这个类对象的id为:{0}'.format(id(Student)))

stu1 = Student('张三')
stu2 = Student('李四')
print(stu1.name + stu2.name)  # 张三李四
print(len(stu1))  # 2
print('stu1这个实例的id为:{0}'.format(id(stu1)))

# object这个类对象的id为:140720285595520
# Student这个类对象的id为:2389500387632
# __new__()被调用执行了,cls的id值为2389500387632
# 创建的对象的id为2389501847312

# __init__()被调用执行了,self的id值为2389501847312
# __new__()被调用执行了,cls的id值为2389500387632
# 创建的对象的id为2389501850192

# __init__()被调用执行了,self的id值为2389501850192




# 类的浅拷贝和深拷贝
print('------------类的浅拷贝和深拷贝---------------')
# 变量的赋值操作:只是形成两个变量,实际上还是指向同一个对象
# 浅拷贝:Python拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用同一个子对象
# 深拷贝:使用copy模块的deepcopy函数拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同

class CPU:
    pass
class Disk:
    pass
class Computer:
    def __init__(self, cpu, disk):
        self.cpu = cpu
        self.disk = disk

# 变量的赋值操作
cpu1 = CPU()
cpu2 = cpu1
print(cpu1)  # <__main__.CPU object at 0x000002A9F219AB00>
print(cpu2)  # <__main__.CPU object at 0x000002A9F219AB00>

# 类的浅拷贝
print('-------------浅拷贝-----------------')
disk = Disk()
computer = Computer(cpu1, disk)
import copy
computer2 = copy.copy(computer)
print(computer, computer.cpu, computer.disk)
print(computer2, computer2.cpu, computer2.disk)
# <__main__.Computer object at 0x00000267A5E5F400> <__main__.CPU object at 0x00000267A5E5F880> <__main__.Disk object at 0x00000267A5E5F430>
# <__main__.Computer object at 0x00000267A5E5F310> <__main__.CPU object at 0x00000267A5E5F880> <__main__.Disk object at 0x00000267A5E5F430>
# Computer类对象不同,拷贝对象的子对象相同

# 类的深拷贝
print('-------------深拷贝-----------------')
computer3 = copy.deepcopy(computer)
print(computer, computer.cpu, computer.disk)
print(computer3, computer3.cpu, computer3.disk)
# <__main__.Computer object at 0x0000026D6EC9F400> <__main__.CPU object at 0x0000026D6EC9F880> <__main__.Disk object at 0x0000026D6EC9F430>
# <__main__.Computer object at 0x0000026D6EC9EEC0> <__main__.CPU object at 0x0000026D6EC9D7B0> <__main__.Disk object at 0x0000026D6EC9D6F0>
# Computer类对象不同,拷贝对象的子对象也不同

模块modules


# 导入模块
# import 模块名称 [as 别名]
# from 模块名称 import 函数/变量/类

import math
print(id(math), type(math))  # 1764080400832 <class 'module'>
print(math.pi)  # 3.141592653589793
print('-------------------------------------')
print(dir(math))
print(math.pow(2, 3), type(math.pow(2, 3)))  # 8.0 <class 'float'>,2的3次方
print(math.ceil(9.001))  # 10,上取整
print(math.floor(9.99))  # 9,下取整


# 导入自定义模块modules2
import modules2
print(modules2.add(1, 2))


# 以主程序的形式运行程序
# 在每个模块的定义中都包括一个记录模块名称的变量__name__,程序可以检查该变量,以确定他们在哪个模块中执行。
# 如果一个模块不是被导入到其它程序中执行,那么它可能在解释器的顶级模块中执行。顶级模块的__name__变量的值为__main__
# if __name__ == '__main__':


# python中的包
# 包是一个分层次的目录结构,它将一组功能相近的模块组织在一个目录下
# 包与目录的区别:包包含__init__.py文件的目录称为包;目录里通常不包含__init__.py文件
# 包的导入:
# import 包名.模块名

# 导入package1包
import package1.module_A as A
print(A.a)  # 10
# 可以直接导入变量
from package1.module_B import b
print(b)  # 20


# python中常用的内置模块:
# sys: Python解释器及其环境操作相关的标准库
# time: 提供与时间相关的各种函数的标准库
# os: 提供了访问操作系统服务功能的标准库
# calendar: 提供与日期相关的各种函数的标准库
# urllib: 用于读取来自网上(服务器)的数据标准库
# json: 用于使用JSON序列化和反序列化对象
# re: 用于在字符串中执行正则表达式匹配和替换
# math: 提供标准算术运算函数的标准库
# decimal: 用于进行精确控制运算精度、有效数位和四舍五入操作的十进制运算
# logging: 提供了灵活的记录事件、错误、警告和调试信息等目志信息的功能

import sys
print(sys.getsizeof(24))  # 28 ,占了28个字节

import time
print(time.time())  # 1657615826.2526894
print(time.localtime(time.time()))  #time.struct_time(tm_year=2022, tm_mon=7, tm_mday=12, tm_hour=16, tm_min=51, tm_sec=0, tm_wday=1, tm_yday=193, tm_isdst=0)

# import urllib.request
# print(urllib.request.urlopen('https://www.baidu.com/').read())


# 第三方模块的安装
# win+R输入cmd打开
# pip install 模块名

def add(a, b):
    return a+b


def div(a, b):
    return a/b


if __name__ == '__main__':
    print(add(10,20))  # 只有作为主程序时才会执行

文件管理


# 字符编码格式:
# Python的解释器使用的是Unicode(内存)
# .py文件在磁盘上使用UTF-8存储(外存)


# 文件的读写操作
# 内置函数open创建文件
# 语法规则:
# file = open(filename [,mode,encoding])
# file:被创建的文件对象;  open():创建文件对象的函数;  filename:要创建或打开的文件名称
# mode:打开模式默认为只读(写操作为w, 读操作为r);  encoding:默认文本文件中的字符编码格式为gbk

file = open('a.txt', 'r')  # r为读操作
print(file.readlines())  # ['123\n', '456\n', '789']
file.close()


# 文件的类别:
# 文本文件:存储的是普通“字符"文本,默认为unicode字符集,可以使用记本事程序打开
# 二进制文件:把数据内容用“字节"进行存储,无法用记事本打开,必须使用专用的软件打开,举例: mp3音频文件,jpg图片.doc文档等

# 打开方式:
# r: 以只读模式打开文件,文件的指针将会放在文件的开头
# w: 以只写模式打开文件,如果文件不存在则创建,如果文件存在,则覆盖原有内容,文件指针在文件的开头
# a: 以追加模式打开文件,如果文件不存在则创建,文件指针在文件开头,如果文件存在,则在文件末追加内容,文件指针在原文件末尾
# b: 以二进制方式打开文件,不能单独使用,需要与其他模式一起使用,rb,或者wb
# +: 以读写方式打开文件,不能单独使用,需要与其他模式一起使用,a+

file = open('b.txt', 'w')
file.write('hello world')
file.close()


# 文件对象的常用方法
# read([size]): 从文件中读取size个字节或字符的内容返回。若省略[size],则读取到文件未尾,即一次读取文件所有内容
# readline(): 从文本文件中读取一行内容
# readlines(): 把文本文件中每一行都作为独立的字符串对象,并将这些对象放入列表返回
# write(str): 把字符串str内容写入文件
# writelines(s_list): 将字符串列表s_list写入文本文件,不添加换行符(写入同一行)
# seek(offset [,whence]): 把文件指针移动到新的位置,offset表示相对于whence的位置:offset:为正往结束方向移动,为负往开始方向移动
#                         whence不同的值代表不同含义:  0:从文件头开始计算(默认值)
#                                                  1:从当前位置开始计算
#                                                  2:从文件尾开始计算
# tell(): 返回文件指针的当前位置
# flush(): 把缓冲区的内容写入文件,但不关闭文件
# close(): 把缓冲区的内容写入文件,同时关闭文件,释放文件对象相关资源


# with语句(上下文管理器)
# with语句可以自动管理上下文资源,不论什么原因跳出with块都能确保文件正确地关闭,以此来达到释放资源的目的
# with open('a.txt', 'r') as file:
# open('a.txt', 'r')称为上下文表达式,结果为上下文管理器(实现了__enter__()方法和__exit__()方法,遵守了上下文管理协议)
# 简单的理解,同时包含 __enter__() 和 __exit__() 方法的对象就是上下文管理器。
# __enter__():进入上下文管理器自动调用的方法,该方法会在 with as 代码块执行之前执行。
#              如果 with 语句有 as子句,那么该方法的返回值会被赋值给 as 子句后的变量;
#              该方法可以返回多个值,因此在 as 子句后面也可以指定多个变量(多个变量必须由“()”括起来组成元组)。
# __exit__():退出上下文管理器自动调用的方法。该方法会在 with as 代码块执行之后执行。
#              如果 with as 代码块成功执行结束,程序自动调用该方法,调用该方法的三个参数都为 None;
#              如果 with as 代码块因为异常而中止,程序也自动调用该方法,使用 sys.exc_info 得到的异常信息将作为调用该方法的参数。

with open('a.txt', 'r') as file:
    print(file.read())


# 目录操作
print('-------------目录操作------------------')
# os模块是Python内置的与操作系统功能和文件系统相关的模块该模块中的语句的执行结果通常与操作系统有关,在不同的操作系统上运行,得到的结果可能不一样。
# os模块与os.path模块用于对目录或文件进行操作

# os模块操作目录相关函数:
# getcwd(): 返回当前工作目录
# listdir(path): 返回指定路径下的文件和目录信息
# mkdir(path[,mode]): 创建目录
# makedirs(path1/path2...[,mode]): 创建多级目录
# rmdir(path): 删除目录
# removedirs(path1/path2...): 删除多级目录
# chdir(path): 将path设置为当前的工作目录

import os
# os.system('notepad.exe')  # 打开记事本
# os.system('calc.exe')  # 打开计算器
# # 直接调用可执行文件
# os.startfile('D:\\tencent\\Bin\\qq.exe')  # 打开qq
#
# print(os.getcwd())  #D:\pycharm\PythonProject\PythonLearning\PythonLearning
# lst = os.listdir('../PythonLearning')  # ../返回上一级目录
# print(lst)


# os.path模块操作目录相关函数:
# abspath(path): 用于获取文件或目录的绝对路径
# exists(path): 用于判断文件或目录是否存在,如果存在返回True,否则返回False
# join(path, name): 将目录与目录或者文件名拼接起来
# splitext(): 分离文件名和拓展名
# basename(path): 从一个目录中提取文件名
# dirname(path): 从一个路径中提取文件路径,不包括文件名
# isdir(path): 用于判断是否为路径

import os.path
print(os.path.abspath('file.py'))  # D:\pycharm\PythonProject\PythonLearning\PythonLearning\file.py
print(os.path.exists('file.py'))  # True
print(os.path.join('D:\\pycharm\\PythonProject\\PythonLearning\\PythonLearning','file.py')) # 拼接
print(os.path.splitext('file.py'))  # ('file', '.py')
print(os.path.basename('D:\\pycharm\\PythonProject\\PythonLearning\\PythonLearning\\file.py'))  # file.py
print(os.path.dirname('D:\\pycharm\\PythonProject\\PythonLearning\\PythonLearning\\file.py'))  # D:\pycharm\PythonProject\PythonLearning\PythonLearning

os demo:

# 列出指定目录下的所有.py文件
import os
path = os.getcwd()  # 返回当前工作目录
lst = os.listdir(path)  # 返回指定路径下的文件和目录信息
# lst = os.walk(path)
# os.walk() 方法用于通过在目录树中游走输出在目录中的文件名,向上或者向下。
for filename in lst:
    if filename.endswith('.py'):
        print(filename)


# os.walk()
import os
path = os.getcwd()  # 返回当前工作目录
lst_file = os.walk(path)
for dirpath, dirname, filename in lst_file:
    print(dirpath)
    print(dirname)
    print(filename)
    print('-----------------------------------------------')

    for file in filename:
        print(os.path.join(dirpath, file))  # 输出文件夹中所有文件的路径

# 不仅可以遍历当前文件,还可以遍历当前文件下的子文件

# D:\pycharm\PythonProject\PythonLearning\PythonLearning
# ['package1', '__pycache__']
# ['A+B.py', 'a.txt', 'abnormal.py', 'b.txt', 'circulate.py', 'class.py', 'dictionary.py', 'file.py', 'function.py', 'if.py', 'list.py', 'modules.py', 'modules2.py', 'object_oriented.py', 'operator.py', 'os_demo1.py', 'pass.py', 'range.py', 'set.py', 'string.py', 'tuple.py']
# -----------------------------------------------
# D:\pycharm\PythonProject\PythonLearning\PythonLearning\package1
# ['__pycache__']
# ['module_A.py', 'module_B.py', '__init__.py']
# -----------------------------------------------
# D:\pycharm\PythonProject\PythonLearning\PythonLearning\package1\__pycache__
# []
# ['module_A.cpython-310.pyc', 'module_B.cpython-310.pyc', '__init__.cpython-310.pyc']
# -----------------------------------------------
# D:\pycharm\PythonProject\PythonLearning\PythonLearning\__pycache__
# []
# ['modules2.cpython-310.pyc', 'operator.cpython-310.pyc', 'string.cpython-310.pyc']
# -----------------------------------------------

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值