python基础与例题

流程控制

if语句

if语句示例:

age = 6
if age > 5:
    print('可以上学了')

if-else语句可以产生两个分支,可根据条件表达式的判断结果选择执行哪一个分支。

name = input('请输入用户名:')
pwd = input('请输入密码:')
if name == 'admin' and pwd == '123':
    print('登录成功')
else:
    print('输入的用户名和密码有误,请重新输入')
    

input函数接受一个标准输入数据,返回为 string 类型。

处理多种情况时,可以使用if-elif-else语句。

if 判断条件1:

条件1为true,执行代码块1

elif 判断条件2:

条件1为false,条件2为true,执行代码块2

elif判断条件3:

else:

以上所有条件都为false,执行代码

score = input('请输入你的积分:')
score = int(score)
if score == 0:
    print('注册会员')
elif score > 0 and score <= 2000:
    print('铜牌会员')
elif 2000 < score <= 10000:
    print('银牌会员')
elif 10000 < score <= 30000:
    print('金牌会员')
else:
    print('钻石会员')

if语句嵌套:

if 判断条件1:

条件1为true,执行代码1

​ if判断条件2:

​ 条件2为true,执行代码2

。。。。

money = input('请输入是否有钱:0代表没钱,1代表有钱:')
if money == '1':
    print('有钱可以上车')
    seat = input('请输入是否有座位:0代表没座位,1代表有座位')
    if seat == '1':
        print('有座位可以坐')
    else:
        print('没有座位就站着')
else:
   print('没钱不能上车')

for循环

for遍历字符串

my = '我叫小明'
for i in my:
    print(i,'hello')    

for range 结合使用

range(n)生成[0,n)可迭代序列(不包含n)

迭代:是指通过重复执行的代码处理相似的数据集的过程,并且本次迭代的处理数据要依赖上一次的结果继续往下做,上一次产生的结果为下一次产生结果的初始状态,如果中途有任何停顿,都不能算是迭代。

可迭代对象:列表,元组,字典,字符串,range函数。

for i in range(4):
    print(i,'hello')

range(start,end,step) 生成[start,end),step是指序列中每两个元素之间的间隔。

for i in range(1,6,2):
    print(i)

for循环的嵌套使用:

for 变量 in 可迭代对象:

​ 代码块1

​ for 变量 in 可迭代对象:

​ 代码块2

#外层for循环,控制打印的行数
for i in range(1,6):
    #内层for循环,控制每行打印的个数
    for j in range(i):
        print('*',end='')
    #一行打印结束后,要输出一个换行
    print()

while循环

while循环是一个条件循环语句,当条件满足时重复执行代码块,直到条件不满足为止。

使用while循环求10!,!代表连乘。

i = 1
result = 1
while i <=10:
    result = result * i
    i+=1
print(result)

while循环中可以嵌套while循环。

while 条件表达式1:

​ 代码块1

​ …

​ while条件表达式2:

​ 代码块2

​ …

使用while循环嵌套打印三角形

i = 1
while i <= 5:
    j = 1
    while j <= i:
        print('*',end='') #end默认 = '\n'
        j+=1
    print()
    i+=1    #每一个循环后面不要忘记+1

break语句

break语句用于跳出离它最近一级的循环,通常与if语句结合使用,放在if语句代码块中。

my = 'itcast'
for i in my:
    if i == 'a':
        break
    else:
        print(i)
my = 'itcast'
i = 0
while i < len(my):  #len()函数用于求字符串的长度,元素的个数。
    if my[i] == 'a':
        break
    else:
     print(my[i])
     i+=1
    

continue语句

continue语句用于跳出当前循环,继续执行下一次循环。

从列表中找出所有正数

for i in [0,-2,5,7,-10]:
    if i <= 0:
        continue
    print(i)

break和continue必须用在循环中

break和continue只对最近的一层循环起作用

列表与元组

列表的创建方式

列表是python中最灵活的有序序列,它可以存储任意类型的元素。开发人员可以对列表中的元素进行添加,删除,修改等操作。

使用中括号创建列表时,只需要在’[]'中使用逗号分隔每个元素即可。

使用list()函数创建列表时,需要给该函数传入一个可迭代类型的数据。

isinstance()函数可用于判断一个对象是否为可迭代对象。

#使用中括号[]创建列表
#1.创建空列表
list1 = []
print(list1,type(list1))
#2.列表中的元素类型均为字符串类型
list2 = ['p','y','t','h','o','n','hello']
print(list2,type(list2))
#3.列表中元素类型不同
list3 = [1,3.14,True,'hello']
print(list3,type(list3))
#使用list()创建列表
#1.创建空列表
list1 = list()
print(list1,type(list1))
#2.创建非空列表list(可迭代对象)
list2 = list('itcast')
print(list2,type(list2))
#list3 = list(1) int类型会报错,int不能迭代
#判断一个对象是否为可迭代对象,是输出true,不是输出false
print(isinstance(list1),Iterable)

访问列表元素

使用索引方式访问列表元素

#使用索引访问列表中指定的元素,索引是从0开始的
list1 = ['java','c#','python','php']
print(list1[1])

使用切片访问列表元素

list1 = ['p','y','t','h','o','n']
#1.获取列表中索引为1至索引为4且步长为2的元素
print(list1[1:4:2])
#2.获取列表中索引为2至末尾的元素
print(list1[2:])
#3.获取列表中索引为0至索引值为3的元素
print(list1[0:3])
#4.获取列表中的所有元素
print(list1[:])
#5.将列表中的所有元素逆置
print(list[::-1])

列表的遍历

案例需求,假设某列表中存储的是会员的名字,可以通过循环遍历该列表,依次向会员推送商品优惠信息。

#嗨,{i}!今日促销,赶快来抢购吧!
list1 = ['章萍','李昊','武田','李彪']
print('今日促销通知!!!')
#for循环实现
for i in list1:
    print(f"嗨,{i}!今日促销,赶快来抢购吧!")
#while循环实现
i = 0
while i < len(list1):
    print(f'嗨,{list1[i]}!今日促销,赶快来抢购吧!')
    i+=1
          

列表的排序

sort()方法能够对列表元素排序,该方法的语法格式如下:

sort(key=none,reverse=false)

key ----- 表示指定的排序规则。

reverse ----- 表示控制列表元素排序的方式。

#列表对象.sort(key,reverse)直接在原列表中进行排序
#key排序的规则,如果不写,默认按照比大小方式排列
#reverse=False,升序排序,reverse=True,降序排序
list1 = [1,5,3,7]
list1.sort()
print(list1)

list2 = [2,6,4,8]
list2.sort(reverse=True)
print(list2)

list3 = ['python','java','php']
list3.sort(key=len,reverse=True)#len函数是求长度,按照列表中数据的长度排序,降序。
print(list3)

sorted方法得到一个新的列表,不会修改原列表的数据

sorted(列表,key,reverse)

list4 = [1,5,3,7]
list5 = sorted(list4)
print(list4)
print(list5)

reverse方法,是将列表中的数据逆置,列表[::-1]会的到一个新的列表。列表.reverse()直接修改原列表,不会创建一个新列表。

list5.reverse()
print(list5)

添加列表元素

append()方法用于在列表末尾添加新的元素。

extend()方法用于在列表末尾一次性添加另一个列表中的所有元素,即使用新列表扩展原来的列表。

insert()方法用于将元素插入列表的指定位置。

list1 = [1,2,3,4]
print(list1)
list1.append(5)
print(list1)

list2 = ['a','b','c']
list3 = [1,2,3]
list2.extend(list3)
print(list2)

list4 = ['a','b','c']
list4.insert(1,'d')
print(list4)


删除列表元素

del语句用于删除列表中指定位置的元素。

remove()方法用于移除列表中的某个元素,若列表中有多个匹配的元素,只会移除匹配到的第一个元素。

pop()方法用于移除列表中的某个元素,如果不指定具体元素,那么移除列表中的最后一个元素。

list1 = ['a','b','c']
del list1[0]
print(list1)

list2 = [1,2,3,4,5]
list2.pop()
print(list2)
list2.pop(2)

list3 = ['h','e','1','1','e']
list3.remove('e')
print(list3)

修改列表元素

修改列表中的元素就是通过索引获取元素并对该元素重新赋值。

list1 = [1,2,3,4,5]
list1[1] = 22  #将索引为1的数据修改为22,即将2改为22
print(list1)

嵌套列表的创建与元素的访问

列表可以存储任何元素,当然也可以存储列表,若列表中存储的元素也是列表,则称为嵌套列表。

#嵌套列表的定义
list1 = [[1,4],[2,5,8],[3,6,9]]
#获取嵌套的内层列表中的数据4
print(list1[0][1])
#向嵌套的内层列表中添加数据
list1[0].append(7)
print(list1)

元组的创建方式

使用圆括号’()'创建元组,并将元组中的元素用逗号进行分隔。

当使用圆括号创建元组时,如果元组中只包含一个元素,那么需要在该元素的后面添加逗号,从而保证python解释器能够识别其为元组类型。

使用tuple()函数创建元组时,如果不传入任何数据,就会创建一个空元组;如果需要创建包含元素的元组,就必须传入可迭代类型的据。

#使用圆括号
#1.创建空元组
tuple1 = ()
print(type(tuple1),tuple1)
#2.元组中的数据相同
tuple2 = ('t','u','p','1','e')
print(type(tuple2),tuple2)
#3.元组中的数据不同
tuple3 = (1,3.14,Ture,'hello')
print(type(tuple3),tuple3)
#使用tuple()创建元组
#4.没有参数,创建空元组
tuple5 = tuple()
print(type(tuple5),tuple5)
#5.传入可迭代类型的数据,创建元组
tuple6 = tuple('hello')
print(type(tuple6),tuple6)

tuple7 = tuple([1,2,3,4])
print(type(tuple7),tuple7)

访问元组元素

元组可以使用索引访问元组中的元素。

元组还可以使用切片来访问元组中的元素。

元组中的元素是不允许修改的,除非在元组中包含可变类型的数据。

元组所谓的“不变”意为元组每个元素的指向永远不变。

#1.使用索引获取单个元素
tuple1 = (1,2,['a','b'])
print(tuple1[0])
print(tuple1[2])
#2.使用切片获取多个数据
print(tuple1[0:2]) #结果为(1,2)
#3.元组中的数据不能被修改,指向不能改变
tuple1[0] = 10 #是错误的
#4.可以修改元组中列表中的数据
tuple1[2][0] = 'python'
print(tuple1)

字典和集合

字典的创建方式

使用花括号“{}”创建字典时,字典的键(key)和值(value)使用冒号连接,每个键值对之间使用逗号分隔。

使用dict()函数创建字典时,键和值使用“=”进行连接。

字典中的键是唯一的。当创建字典时出现重复的键——若使用dict()函数创建字典,提示语法错误;若使用花括号创建字典,键对应的值会被覆盖。

#1.使用大括号创建
#1.1创建空字典
dict1 = {}
print(type(dict1),dict1)
#1.2创建非空字典{键:值}
dict2 = {'name':'itcast','addr':'北京'}
print(dict2)
#2.使用dict()创建
#2.1创建空字典
dict4 = dict()
print(type(dict4),dict4)
#2.2创建非空字典dict(键=值)
dict5 = dict(name='tom',age=18)
print(dict5)


通过“键”访问字典

因为字典中的键是唯一的,所以可以通过键获取对应的值。

为了避免引起keyerror异常,当访问字典元素时可以先使用in与not in检测某个键是否存在。

color = {'red':'红色','black':'黑色','white':'白色'}
if 'red' in color:
    print(color['red'])
else:
    print('键不存在')

字典元素的添加和修改

字典可以通过update()方法或指定的键添加元素。

#字典元素的添加和修改
dict1 = {'stu1':'小明'}
print(dict1)
#1.update方法(键=值)
#1.1键不存在,添加数据
dict1.update(stu2='小红')
print(dict1)
#1.2键存在stu2,修改数据(元素)
dict1.update(stu2='小刚')
print(dict1)
#2.通过键(key)添加和修改 字典名['键'] = 值
#2.1键不存在,添加数据
dict1['stu3'] = '小兰'
print(dict1)
#2.2键存在stu3,修改数据(元素)
dict1['stu3'] = '小花'
print(dict1)

字典元素的删除

pop()方法可以根据指定的键删除字典中的指定元素,若删除成功则返回目标元素的值。

popitem()方法可以随机删除字典中的元素,若删除成功则返回目标元素。

clear()方法用于清空字典中的元素。

dict1 = {'001':'张三','002':'李四','003':'王五','004':'赵六','005':'小明'}
print(dict1.pop('005'))
print(dict1.popitem())
print(dict1.clear())

字典元素的查询

使用items()方法可以查看字典的所有元素。

使用keys()方法可以查看字典中所有的键。

使用values()方法可以查看字典的所有值。

三种方法都支持迭代操作。

dict1 = {'001':'张三','002':'李四','003':'王五','004':'赵六'}
#1.查询所有的元素
print(dict1.items())
for i in dict1.items():
    print(i)
#2.查询所有的键(key)
print(dict1.keys())
for i in dict1.keys():
    print(i)
#3.查询所有的值(value)
print(dict1.values())
for value in dict1.values():
    print(value)
    

集合的创建方式

集合分为可变集合与不可变集合。

可变集合:由set()函数创建,集合中的元素可以动态地增加或删除。

不可变集合:由frozenset()函数创建,集合中的元素不可改变。

可以直接使用花括号创建可变集合,花括号中的多个元素以逗号分隔。

集合中的数据必须是不可变类型,并且数据是没有重复的。

#1.可变集合的创建
set1 = set()
print(type(set1),set1)

set2 = set([1,2,3,4])
print(set2)

set3 = {'a','b','c'}
print(set3)

set4 = frozenset((1,2,3,'a','b'))
print(set4)



集合元素的添加,删除和清空

可变集合的add()或update()方法都可以实现向集合中添加元素,其中add()方法只能添加一个元素,而update()方法可以添加多个元素。

remove()方法用于删除可变集合中的指定元素。

discard()方法可以删除指定的元素,但若指定的元素不存在,该方法不执行任何操作。

clear()方法可以情空可变集合中的元素。

#创建空集合
set1 = set()
print(set1)
#1.集合元素的添加
#1.1add(数据)
set1.add('python')
print(set1)
#1.2update(可迭代对象),将可迭代对象中的每一个数据添加到集合中
set1.update(['C','C++','java','php'])
print(set1)
#2.集合元素的删除
#2.1remove()根据元素值删除,如果元素不存在,发生异常
set1.remove('C')
print(set1)
#2.2diccard()根据元素值删除,如果元素不存在,不进行操作
set1.discard('aaa')
print(set1)
#2.3pop()随机删除
set1.pop()
print(set1)
#3.集合元素的清空clear()
set1.clear()
print(set1)


集合类型的操作符

联合操作是将集合seta与集合setb合并成一个新的集合。联合使用“|”符号实现。

交集操作是将集合seta与集合setb中相同的元素提取为一个新的集合。交集使用“&”符号实现。

差补操作是将只属于集合seta或者只属于集合setb中的元素作为一个新的集合。差补使用“-”符号实现。

对称差分操作是将只属于集合seta与只属于集合setb中的元素组成一个新的集合。对称差分使用^符号实现。

seta = {'a','c'}
setb = {'b','c'}
result = seta | setb
print(result)

print(seta & setb)

print(seta - setb)
print(setb - seta)

print(seta ^ setb)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q1Xj3W59-1605844582182)(C:\Users\song\AppData\Roaming\Typora\typora-user-images\image-20200928152302425.png)]

函数

函数的定义

函数指被封装起来的,实现某种功能的一段代码。python安装包,标准库中自带的函数统称为内置函数,用户自己编写的函数称为自定义函数,不管是哪种函数,其定义和调用方式都是一样的。

若函数的参数列表为空,这个函数称为无参函数。

函数定义之时可以设置参数列表,以实现更灵活的功能。

#函数的定义,不会执行函数中的代码
#无参函数的定义
def show1():
    print('我的名字是小明')
    print('年龄是18岁')
#有参函数的定义
def show2(name,age): #name和age是形式参数:不是实际存在的变量。
    print(f'我的名字是{name}')
    print(f"年龄是{age}")
    
    

函数的调用

定义好的函数直到被程序调用时才会被执行。

调用带有参数的函数时需要传入参数,传入的参数称为实际参数,实际参数是程序执行过程中真正会使用的参数。

#函数的调用会执行函数中的内容
def show1():
    print('我的名字是小明')
    print('年龄是18岁')
#有参函数的定义
def show2(name,age): #name和age是形式参数:不是实际存在的变量。
    print(f'我的名字是{name}')
    print(f"年龄是{age}")
    
show1() #函数的调用,函数名字()

#有参函数的调用 函数名字(参数) 参数的个数要和定义的时候一样
#称为实际参数
show2('小红',17)




    

位置参数

函数的参数传递是指将实际参数传递给形式参数的过程。根据不同的传递形式,函数的参数可分:

(位置参数,默认值参数,关键字参数,不定长参数)

调用函数时,解释器会将函数的实际参数按照位置顺序依次传递给形式参数。

#位置参数:函数调用时,将实际参数的值按照顺序传递给形式参数
def show1(name,age):
    print(f'我的名字是{name}')
    print(f"年龄是{age}")
show1('小明',18)


关键字参数

关键字参数通过“形式参数=实际参数”的格式将实际参数与形式参数相关联,根据形参的名称进行参数传递。

def show2(name,age,gender):
    print(f'我的名字是{name}')
    print(f"年龄是{age}")
    print(f"性别是{gender}")

show2(name='小明',age=18,gender='男')

默认参数

定义函数时可以指定形式参数的默认值。调用函数时,可分为以下两种情况:

未给默认参数传值:使用参数的默认值

给默认参数传值:使用实际参数的值

#ip没有默认值,在调用的时候需要传递实参值,port存在默认值3306,可以传递实参值,也可以不传递。
def connect(ip,port=3306):
    print(f'连接地址为{ip}')
    print(f'连接的端口为{port}')
    print('连接成功')
#函数调用:默认参数不传递参数值,使用默认值
connect('127.0.0.1')
#函数调用:默认参数传递实参值
connect('127.0.0.1',port=8081)
    

不定长参数

若要传入函数中的参数的个数不确定,可以使用不定长参数。不定长参数也称可变参数,此种参数接收参数的数量可以任意改变。

不定长参数 *args用于接收不定数量的位置参数,调用函数时传入的所有参数被 *args接受后以元组形式保存。

** kwargs用于接受不定数量的关键字参数,调用函数时传入的所有参数被 ** kwargs接收后以字典形式保存。

def func(*args,**kwargs)
    print(args) 
    print(kwargs)
func(1,2,3,4,a=5,b=6,c=7)

局部变量

变量的作用域是指变量的作用范围。根据作用范围,python种的变量分为局部变量与全局变量。

局部变量是在函数内定义的变量,只在定义它的函数内生效。

def func():
    name = '小明' #局部变量,只能在函数内部使用
    print(name)
#函数调用
fun()
#在函数外部使用局部变量
#print(name) 是错误的

全局变量

全局变量是在函数外定义的变量,它在程序中任何位置都可以被访问。

函数中只能访问全局变量,但不能修改全局变量。

若要在函数内部修改全局变量的值,需先在函数内使用关键字”global“进行声明。

#定义全局变量
value = 100
def value1():
    print(value) #访问全局变量
def value2():
    global value
    value = 200
value1()
value2()

    

匿名函数

匿名函数是无需函数名标识的函数,它的函数体只能是单个表达式。python中使用关键字lambda定义匿名函数。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qHRtCgfX-1605844582186)(C:\Users\song\AppData\Roaming\Typora\typora-user-images\image-20200928164524330.png)]

为了方便使用匿名函数,应使用变量记录这个函数。

#无参的匿名函数
func1 = lambda : print('好好学习')
func1()

#有参的匿名函数
#方法一
func2 = lambda a,b: a * b
print(func2(10,3))
#方法二
func2 = lambda a,b: print(a * b)
func2(10,3)


递归函数

递归是一个函数过程在定义中直接调用自身的一种方法,它通常把一个大型的复杂问题层层转化为一个与原问题相似,但规模较小的问题进行求解。

如果一个函数中调用了函数本身,这个函数就是递归函数。

递归函数只需少量代码就可描述出解题过程所需要的多次重复计算,大大地减少了程序地代码量。

函数递归调用时,需要确定两点:一是递归公式,二是边界条件。

递归公式:是递归求解过程中的归纳项,用于处理原问题以及与原问题规律相同的子问题。

边界条件:边界条件即终止条件,用于终止递归。

调用5的阶乘
def fact(num):
    if num == 1
       return 1
    else:
       return num * fact(num-1)

常用内置函数

abs()函数用于计算绝对值,其参数必须是数字类型。如果参数是一个复数,那么abs()函数返回的绝对值是此复数与它的共轭复数乘积的平方根。

ord()函数用于返回字符在unicode编码表中对应的码值,其参数是一个字符。

chr()函数和ord()函数功能相反,其参数是一个整数。

print(abs(-1))
print(ord('a'))
print(chr('65'))

类与面向对象

面向对象概述

面向过程编程的基本思想是:分析解决问题的步骤,使用函数实现步骤相应的功能,按照步骤的先后顺序依次调用函数。

面向过程只考虑如何解决当前问题,它着眼于问题本身。

面向对象编程的基本思想是:首先会从问题之中提炼出问题涉及的角色,将不同角色各自的特征和关系进行封装,以角色为主体,通过描述角色的行为去描述解决问题的过程。

面向对象编程的着眼之处在于角色以及角色之间的联系。

角色之间相互独立,但相互协作,流程不再由单一的功能函数实现,而是通过调用与角色相关的方法来完成。

面向对象的基本概念

对象是构成世界的一个独立单位,它由数据(描述事物的属性)和作用于数据的条件(体现事务的行为)构成一个独立整体。

类是具有相同属性和行为的一组对象的集合,它提供一个抽象的描述,其内部包括属性和方法两个主要部分,它就像一个模具,可以用它铸造一个个具体的铸件。

抽象是抽取特定实例的共同特征,形成概念的过程。

封装是面向对象的核心思想,将对象的属性和行为封装起来,不需要让外界指定具体实现细节,这就是封装思想。

继承描述的是类与类之间的关系,通过继承,新生类可以在无需赘写原有类的情况下,对原有类的功能进行扩展。

多态指同一个属性或行为在父类及其各派生类中具有不同的语义。

类和对象的关系:

类是对多个对象共同特征的抽象描述,它是对象的模板。

对象用于描述现实中的个体,它是类的实例。

类的定义与访问

类中可以定义数据成员和成员函数,数据成员用于描述对象特征,成员函数用于描述对象行为,其中数据成员也被称为属性,成员函数也被称为方法。

#定义一个Car类
class Car(object):
    #属性:事物的属性
    wheels = 4
    #方法:事物的行为动作或者功能
    def driver(self):
        print('开车的方法')
    def stop(self):
        print('停车的方法')
    

对象的创建与使用

若想在程序中真正地使用对象,需掌握访问对象成员地方式。对象成员分为属性和方法,他们的访问格式分别如下:

对象名.属性 对象名.方法()

#定义一个Car类
class Car(object):
    #属性:事物的属性
    wheels = 4
    #方法:事物的行为动作或者功能
    def driver(self):
        print('开车的方法')
    def stop(self):
        print('停车的方法')
#1.创建对象
car1 = Car()
#2.获取对象属性值和调用对象方法
print(car1.wheels)
car1.driver()
car2.driver()
#3.给对象添加属性
#语法格式:对象名.属性名 = 属性值
car1.name = '马'
print(car1.name)

访问限制

类中定义的属性和方法默认为共有属性和共有方法,该类的对象可以任意访问类的共有成员。

class Penson(object):
    weight = 55
    def info(self):
        print(f'我的体重是{self.weight})
person = Person()
print(person.weight)
person.info()

可以通过类成员名之前添加双下划线_ _来限制成员的访问权限。

class Penson(object):
    __weight = 55
    def __info(self):
        print(f'我的体重是{self.__weight})
    def get(self):
        print(self.__weight)
        self.__info()
person = Person()
person.get()


构造方法

_ init _()方法按照参数的有无(self除外,因为self是默认参数)可分为有参构造方法和无参构造方法。

无参构造方法:可以为属性设置初始值,此时使用该方法创建的所有对象都具有相同的初始值。

有参构造方法:可以使用参数为属性设置初始值,此时使用该方法创建的所有对象都具有不同的初始值。

#定义一个无参数的构造方法
class Information(object):
    #定义一个无参数的构造方法:是用来给对象添加属性和设置相同的属性值,self指的是该类创建出来的对象
    def __init__(self):
        self.color = '黄皮肤'
xiaoli = Information()
print(xiaoli)
#定义一个有参数的构造方法
class Information(object):
     #定义一个有参数的构造方法:是用来给对象添加属性和设置不相同的属性值,self指的是该类创建出来的对象
    def __init__(self,name.age):
        self.color = '黄皮肤'
        self.name = name
        self.age = age
xiaoli = Information('xiaoli',20)
print(xiaoli)
print(xiaoli.name)
print(xiaoli.age)

对象属性和类属性的区别:对象属性只能使用对象进行访问,不能使用类进行访问。类属性可以使用类和对象进行访问。

析构方法

getrefcount()函数是sys模块中用于统计对象引用数量的函数,其返回结果通常比预期的结果大1。

当一个对象的引用计数器数值为0时,就会调用_ del _()方法,这个方法就是类的析构方法。

#__del__:表示对象销毁的时候会调用该方法,目的:检测对象是否被销毁。
#对象销毁的情况:
#1.在程序运行结束后,程序中所使用的数据都要在内存中进行销毁
#2.在程序运行期间,数据没有被变量使用的时候,该数据对象也会在内存中销毁。
import sys
class Destruction(object):
    def __def__(self):
        print('该对象被销毁掉')
destruction = Destruction()
print(sys.getrefcount(destruction))

 

类方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4RWm4WZ7-1605844582187)(C:\Users\song\AppData\Roaming\Typora\typora-user-images\image-20200928191228803.png)]

类方法可以被类名或对象名调用,其语法格式如下:

类名.类方法

对象名.类方法

在实例方法中无法修改类属性的值,但在类方法中可以修改类属性的值。

class Apple(object):
    #定义一个类属性
    count = 0
    #定义实例方法
    def add(self):
        self.count = 1
        print('执行了实例方法')
apple = Apple()
apple.add()
    #定义类方法
    @classmethed
    def add1(cls):
        cls.count=2
        print('执行了类方法')
apple = Apple()
apple.add1()
print(Apple.count)
Apple.add1()

静态方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GdjhvCaH-1605844582189)(C:\Users\song\AppData\Roaming\Typora\typora-user-images\image-20200928192149066.png)]

class Apple(object):
    #定义一个类属性
    count = 0
    #定义静态方法
    @staticmethod
    def method():
        print(Apple.count)
        Apple.add1()
        Apple.add()
apple = Apple()
apple.method()
#静态方法可以使用类和对象进行访问,在静态方法中可以通过类名.方法名或者类名.属性名访问类的成员
    

单继承

单继承指的是子类只继承一个父类,其语法格式如下:

class 子类(父类)

class Amphibian(object):
    name = '两栖动物'
    def features(self):
        print('幼年使用鳃呼吸')
        print('成年使用肺兼皮肤呼吸')
#定义一个子类
class Frog(Amphibian):
    def attr(self):
        print(f'青蛙是{self.name}')
        print('青蛙会呱呱叫')
forg = Frog()
print(forg.name)
frog.features()
frog.attr()
 

多继承

多继承指的是一个子类继承多个父类,其语法格式如下:

class 子类 (父类A,父类B,…):

#定义一个父类
class English(object):
    def know(self):
        print('具备英语知识')
#定义另一个父类
class Math(object):
    def konw1(self):
        print('具备教学知识')
#定义一个子类
class Student(English,Math):
    def study(self):
        print('学习的任务是学习')
stu = Student()
stu.know()
stu.know1()
stu.study()

方法的重写

子类可以继承父类的属性和方法,若父类的方法不能满足子类的要求,子类可以重写父类的方法,以实现理想的功能。

class Felines(object):
    def speciality(self):
        print('猫科动物的特长是爬树')
class Cat(Felines):
    def speciality(self):
        print('猫会爬树')
        print('猫会抓老鼠')
cat = Cat()
cat.speciality()
    

super()函数

如果子类重复写了父类的方法,但仍希望调用父类中的方法,那么可以使用super()函数实现。

class Felines(object):
    def speciality(self):
        print('猫科动物的特长是爬树')
class Cat(Felines):
    def speciality(self):
        print('猫会爬树')
        print('猫会抓老鼠')
        super().speciality()
cat = Cat()
cat.speciality()
    

多态

多态:对象调用同一个方法会出现不同的表现形式或者不同的结果,那么该操作便是多态。

多态的使用场景:强掉的是对象想要完成同一个功能,此时便可以想到多态。

注意:使用多态的时候必须提供一个统一的调用函数或者方法,使用该函数或者方法完成多态的操作。

class Animal(object):
    def move(self):
        pass
class Rabbit(Animal):
    def move(self):
        print('兔子通过蹦蹦跳跳进行移动')
class Snall(Animal):
    def move(self):
        print('蜗牛通过缓慢爬行进行移动')
def move(obj):obj表示形参,是用来接受都能够进行移动的对象,比如兔子和蜗牛对象。利用多态的操作完成动物移动的功能。
    obj.move()
rabbit = Rabbit()
move(rabbit)

snail = Snail()
move(snail)

    
      

模块

模块的概念

在python程序中,每个.py文件都可以视为一个模块,通过在当前.py文件中导入其它.py文件,可以使用被导入文件中定义的内容。

python中的模块分为三类,分别是内置模块,第三方模块和自定义模块。

内置模块:python的官方模块,可直接导入程序供开发人员使用。

第三方模块:由非官方制作发布的,供给大众使用的python模块,在使用之前需要开发人员先自行安装

自定义模块:开发人员在程序编写的过程中自行编写的,存放功能性代码的.py文件。

模块的导入方式

使用import导入模块的语法格式如下:

import 模块1,模块2,。。。

模块导入之后便可以通过"."使用模块中的函数或类。

模块名.函数名()/类名

如果开发过程中需要导入一些名称较长的模块,可以使用AS为这些模块起别名,语法格式如下:

import 模块名 as 别名

使用from…import…方式导入模块之后,无需添加前缀,可以像使用当前程序中的内容一样使用模块中的内容,此种方式的语法格式如下:

from 模块名 import 函数/类/变量

from…import…也支持一次导入多个函数,类,变量等,函数与函数之间使用逗号分隔。

利用通配符“*”可以使用from…import…导入模块中的全部内容。

from…import…也支持为模块或模块中的函数起别名。

常见的标准模块

python内置了许多标准模块,列如sys,os,random和time模块等。

sys模块中提供了一系列与python解释器交互的函数和变量,用于操控python的运行时环境。

os模块中提供了访问操作系统服务的功能。

random模块为随机数模块,该模块中定义了多个可产生各种随机数的函数。

time模块中提供了一系列处理时间的函数。

#1.sys模块
#sys.argv获取命令行参数列表,该列表中的第一个元素是程序自身所在路径
import sys
print(sys.argv)
#sys.version获取python解释器的版本信息
print(sys.version)
#sys.path获取模块的搜索路径,该变量的初值为环境变量pythonpath的值
print(sys.path)
#sys.platfrom返回操作系统平台的名称
print(sys.platfrom)
#sys.exit()退出当前程序。一设置返回值或退出信息,正常退出返回值为0
print(sys.exit())

#2.os模块
import os
#os.getcwd()获取当前工作路径,即当前python脚本所在的路径
print(os.getcwd())
#os.chdir()改变当前脚本的工作路径
os.chdir('C:\\User...')
#os.remove()删除指定文件
os.remove('test')
#os._exit()终止python程序
os._exit(0)
print('exit')
#os.path.abspath(path)返回path规范化的绝对路径
print(os.path.abspath('标准模块.py'))
#os.path.split(paht)将path分隔为形如(目录,文件名)的二元组并返回
print(os.path.split(os.path.abspath('常见的标准模块.py')))

#3.random模块
#import random
#random.random()返回(0,1]之间的随机实数
print(random.random())
#random.randint(x,y)返回[x,y]之间的随机整数
print(random.randint(0,5))
#random.chocie(seq)从序列seq中随机返回一个元素
list = [1,2,3,4,5]
print(random.choice(list))
#random.uniform(x,y)返回[x,y]之间的随机浮点数
print(random.uniform(0,5))

#4.time模块
import time
#time.time()获取当前时间,结果为实数,单位为秒
print(time.time())
#time.sleep(secs)进入休眠态,时长由参数secs指定,单位为秒
time.sleep(3)
#time.strptime(string[,format])将一个时间格式(如 2019-02-25)的字符串解析为时间元组
str1 = '2019-02-25'
str2 = time.strptime(str1,'%Y-%m-%d')
print(str2)
#time.localtime([secs])以str2类型输出本地时间
print(time.localtime())
#time.asctime([tuple])获取时间字符串,或将时间元组转换为字符串
print(time.asctime(str2))


模块的导入特性

_ all _属性实际上是一个元组,该元组中包含的元素决定了在使用from…import * 语句导入模块内容时通配符*所包含的内容。

如果 _ all _中只包含模块的部分内容,那么from…import * 语句只会将 _ all _中包含的部分内容导入程序。

在calc模块中设置_ all _属性为[“add”,“subtract”],此时其他python文件导入calc模块后,只能使用calc模块中的add()与subtract()函数。

通过“from…import*"方式导入calc模块,然后使用该模块中的add()

与subtract()函数。

为了避免项目运行时执行这些测试代码,python中设置了_ name _属性。

_ name _属性通常与if条件语句一起使用,若当前模块是启动模块,则其 _ name _的值为” _ main _";若该模块被其它程序导入,则 _ name _的值为文件名。

__all__ =['add','subtract']

if __name__ == '_main_'#下面这些代码在另一个导入包中是不被执行的
   print(add(1,2))
   print(subtract(1,2))

包的结构

python中的包是一个包含_ init _.py文件的目录,该目录下还包含一些模块以及子包。

包中的_ init _.py文件可以为空,但必须存在,否则包将退化为一个普通目录。

_ init _.py文件有两个作用,第一个作用是标识当前目录是一个python的包;第二个作用是模糊导入。如果 _ int _文件没有声明 _ all _ 属性,那么使用from … import * 导入的内容为空。

#包1名字是module
def add(a,b):
    print(a+b)
#包2要写入__all__属性
__all__ = ['module']
#导入包1
from package import *
module.add(1,2)

包的导入

使用import导入包中的模块时,需要在模块名的前面加上包名,格式为“包名.模块名”。若要使用已导入模块中的函数时,需要通过“包名.模块.函数”实现。

通过from…import…导入包中模块包含的内容,若需要使用导入模块中的函数,需要通过“模块.函数”实现。

def add(a,b):
    print(a+b)
#1.使用import方式
import package.demo
package.demo.add(1,2)
#2.使用from...import...方式
from package import demo
demo.add(1,2)

文件与文件路径操作

打开文件

计算机中的文件能够持久保存程序运行时产生的数据。

open()函数用于打开文件,该函数调用成功会返回一个文件对象。

open(file,mode=‘r’,encoding=None)

file:表示待打开文件的文件名。

encoding:表示文件的编码格式。

mode:表示文件的打开模式。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XkEUO9ww-1605844582191)(C:\Users\song\AppData\Roaming\Typora\typora-user-images\image-20200929110923151.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5QqJEOfs-1605844582191)(C:\Users\song\AppData\Roaming\Typora\typora-user-images\image-20200929110956374.png)]

f = open('file','r',encoding='utf-8')
print(f)
#encoding:指定打开文件的编码格式,如果没有指定,那么在windows中默认是以gbk的格式打开文件的
#在mac或Linux系统中默认是以utf-8的格式打开文件

关闭文件

close()方法用于关闭文件,该方法没有参数,直接调用即可。

文件对象.close()

程序执行完毕后,系统会自动关闭由该程序打开的文件,但计算机中可打开的文件数量是有限的,每打开一个文件,可打开文件数量就减一;打开的文件占用系统自愿,若打开的文件过多,会降低系统性能。因此,编写程序时应使用close()方法主动关闭不在使用的文件。

f = open('file','r',encoding='utf-8')
print(f)
#encoding:指定打开文件的编码格式,如果没有指定,那么在windows中默认是以gbk的格式打开文件的
#在mac或Linux系统中默认是以utf-8的格式打开文件
f.close()

文件的读取

read()方法可以从指定文件中读取指定数据,其语法格式如下:

文件对象.read([size])

参数size表示设置的读取数据的字节数,若该参数缺省,则一次读取指定文件中的所有数据。

readline()方法可以从指定文件中读取一行数据,其语法格式如下:

文件对象.readline()

每执行一次readline()方法便会读取文件中的一行数据。

readlinues()方法可以一次读取文件中的所有数据,其语法格式如下:

文件对象.readlines()

readlinues()方法在读取数据后会返回一个列表,该列表中的每个元素对应着文件中的每一行数据。

read()(参数缺省时)和readlines()方法都可一次读取文件中的全部数据,但这两种操作都不够安全。因为计算机的内存是有限的,若文件较大,read()和readlines()的一次读取便会耗尽系统内存。为了保证读取安全,通常多次调用read()方法,每次读取size字节的数据。

#使用read()方法,如果不传入参数,那么则读取文件中所有的内容
print(f.read())
#使用read(5)方法,如果传入参数,那么则读取文件中指定长度的内容。
print(f.read())
#使用readline()方法,不需要传入参数,只要执行一次就读取文件中的一行数据
print(f.readline())
#使用readlinues()方法,不需要传入参数,只要执行一次就会读取文件中的所有内容,返回的是一个列表。列表中的每一个元素就是文件中的一行数据
print(f.readlines())
f.close()

数据写入

通过write()方法向文件中写入数据,其语法格式如下。

文件对象.write(str)

参数str表示要写入的字符串。若字符串写入成功,write()方法返回本次写入文件的长度。

writelines()方法用于向文件中写入字符串序列,其语法格式如下:

文件对象.writelines([str])

#write()方法:参数只能是字符串类型
f = open('test','w',encoding='utf-8')
result = f.write('hello')
print(result)
f.close()
#wb:打开二进制文件,不需要指定编码格式
f2 = open('test1','wb')
byte = '传智播客',encode('utf-8')
print(byte)
f2.write(byte)
f2.close()
#writelines方法:参数是以序列字符串的方式写入,python中的序列指的是python中的字符串,列表,元组,字典,集合,这些数据类型,除了字符串之外,其他序列中的元素必须是字符串类型。
f3 = open('text','w',encoding='utf-8')
f3.witelines('hello itcast\n')
f3.close()

文件的读取

在文件的一次打开与关闭之间进行的读写操作都是连续的,程序总是从上次读写的位置继续向下进行读写操作。

实际上,每个文件对象都有一个称为“文件读写位置”的属性,该属性用于记录文件当前读写的位置。

tell()方法用于获取当前文件读写的位置,其语法格式如下:

文件对象.tell()

seek()方法用于设置当前文件读写位置,其语法格式如下:

文件对象.seek(offset,from)

offset:表示偏移量,即读写位置需要移动的字节数;

from:用于指定文件的读写位置,该参数的取值有:0,1,2,其中0表示在开始位置读写;1表示在当前位置读写;2表示在末尾位置读写。

f = open('test','r',encoding='utf-8')
print(f.tell())
f.read(5)
print(f.tell())
f.close()

f = open('test','r',encoding='utf-8')
print(f.tell())
f.seek(5,0)
print(f.tell())
print(f.read(5))
f.close()

文件的复制

文件拷贝即创建文件的副本,此项操作的本质仍是文件的打开,关闭与读写,基本逻辑如下:

1.打开文件 2.读取文件内容 3.创建新文件,将数据写入到新文件中

4.关闭文件,保存数据。

f1 = open('test','r',encoding='utf-8')
result = f1.read()
print(result)
f1.close()

f2 = open('test1','w',encoding='utf-8')
f2.write(result)
f2.close()

文件的重命名

python提供了用于更改文件名的函数,rename(),该函数存在于os模块中,其语法格式如下:

rename(原文件名,新文件名)

import os
os.rename('file','file1')

创建目录

os模块中的mkdir()函数用于创建目录,其语法格式如下:

os.mkdir(path,mode)

path:表示要创建的目录。

mode:表示目录的数字权限,该参数在windows系统下可忽略。

import os
os.mkdir('demo')

结论mkdir不能在创建一个已存在的目录

os.path.exists():是用来判断程序中的目录或文件是否存在,如果存在返回True,否则为False

print(os.path.exists('demo'))
if os.path.exists('demo'):
    print('该目录已经存在')
else:
    os.mkdir('demo')
    print('目录创建成功')
    

删除目录

使用python内置模块shutil中的rmtree()函数可以删除目录,其语法格式如下:

rmtree(path) 参数path表示要删除的目录。

import shutil
#shutil.rmtree('demo')
#结论:retree必须删除的是已存在的目录,否则程序将会报错

import os 
if os.path.exists('demo'):
     shutil.rmtree('demo')
     print('该目录已删除')
elseprint('该目录不存在')

获取目录的文件列表

os模块中的listdir()函数用于获取文件夹下文件或文件名的列表,该列表以字母顺序排序,其语法格式如下:

listdir(path) 参数path表示要获取的目录列表。

import os
print(os.listdir())
#指定目录,获取指定目录下的所有文件名和文件夹名
path = os.getcwd()
print(path)
print(os.listdir(path + '//demo'))

相对路径与绝对路径

文件相对路径指这个文件夹所在的路径与其它文件(或文件夹)的路径关系,绝对路径指盘符开始到当前位置的路径。

isabs()函数可以判断目标路径是否为绝对路径,若为绝对路径返回True,否则返回False。

当目标路径为相对路径时,使用abspath()函数可将当前路径规范化为绝对路径。

import os
print(os.path.isabs('test'))

print(os.path.abspath('demo'))

路径的拼接

os.path模块中的join()函数用于拼接路径,其语法格式如下:

os.path.join(path1[,path2[,…]])

参数path1,path2表示要拼接的路径。

如果最后一个路径为空,则生成的路径将以一个""结尾。

import os
path1 = 'C:\\users'
path2 = 'test'
print(os.path.join(path1,path2))

path1 = 'C:\\users'
paht2 = ''
print(os.path.join(path1,path2))

错题分析

判断一个数是不是素数。

import math
n = input('input an inter:')
n = int(n)
m = math.ceil(math.sqrt(n)+1)
for i in range(2,m):
    if n%i == 0 and i <n:
        print('No')
        break
    else:
       print('Yes')
#判断一个数是不是素数,首先看到数字要先想到math模块,其次用input函数输入一个数,素数是个自然数,所有要把他转换为整数,判断一个素数是否只有1和它本身的因数,需要用到n%i是否等于0。

python是以缩进来标记代码块的,代码块一定要有缩进,没有缩进的不是代码块。另外,同一个代码块的缩进量要相同,缩进量不同的不属于同一个代码块。不同的代码块会执行出不想要的结果。

Python 中使用了分号作为语句分隔符,但是不用分号作为终止符, 而是用了换行作为终止符。若在一句完整的语句末尾加了分号,然后换行,那么 IDE 一般会提示“Trailing semicolon in the statement”,提示着这个“尾随分号”是多余的。

Python 不用分号作为终止符,大概有如下的原因:

  1. 它把缩进和换行当成文法的有效部分,可以表达出完整的语义,不会导致编译时的歧义。这是最主要的原因,是跟“分号党”的根本区别
  2. 不用分号与花括号,但是使用缩进和冒号,这是一脉相承的思路,总体上形成了更高的可读性、简洁性和标准化。这体现了局部语法与整体规则的关系,1 + 1 > 2
  3. 可以少写字符,也避免了在某些键盘上要敲“shift”键的麻烦
  4. 分号主要是给机器看的,但 Python 更注重于人性化。早期硬件有所限制,加分号可以提升解析/编译的速度,但如今障碍已除,某些分号党语言只是在延续 B/C 语言的老传统
  5. 对于需要换行的语句,Python 中使用反斜杠(\)来连接,可以理解成它把换行给转义了,能够解决一句多行的问题

打印出菱形

for i in range(4):
    for j in range(2-i+1):
        print(" ",end="")
    for k in range(2*i+1):
        print("*",end="")
    print()
for i in range(3):
    for j in range(i + 1):
        print(" ",end="")
    for k in range(4 - 2 * i + 1):
        print("*",end="")
    print()
#打印菱形首先要想到每一行除了中间的星号外,要想到每一行第一个星号前面打印几个空格,从第一行往下依次减少一个空格到中间为止。在依次增加一个空格。然后打印星号需要依次打印,就要用到循环,可以使用for循环在配合range函数使用,然后再想出符号range函数中的参数。每一行打印完需要换行,没打印完要输出空字符。

利用递归方法求5!。

#方法1
def fact(j):
    sum = 0
    if j == 0:
        sum = 1
    else:
        sum = j * fact(j-1)
    return sum
print(fact(5))
#递归方法首先要想到函数然后定义一个函数在函数中使用递归方法,为了防止0*任何数都得零就要先把等于0得值转换成1,然后再定义一个依次减一得参数,并返回值。
#方法2
import math as ma
x = int(input())
print(ma.factorial(x))
#factorial求所有函数的阶乘

按逗号分隔列表。

o = [1,2,3,4,5]
s1 = ','.join(str(n) for n in o)
print(s1)
#join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。

从100个数中随机生成10个数

#方法1
import random
for i in range(1,11):
    print(random.randint(1,101))
#方法2使用列表方法
import random
x = []
for i in range(1,11):
    x.append(random.randint(1,101))
    print(x)
#方法3使用sample函数
import random
num = range(1,101)
nums = random.sample(num,10)
print(nums)
#sample(序列a,n)从序列a中随机抽取n个元素,并将n个元素以list形式返回

错误与异常

概述

SyntaxError:发生语法错误时引发

FileNotFoundError:未找到指定文件或目录时引发

NameError:找不到指定名称的变量时引发

ZeroDivisionError:除数为0时的异常

IndexError:当使用超出列表范围的索引时引发

KeyError:当使用映射不存在的键时引发

AttributeError:当尝试访问未知对象属性时引发

TypeError:当试图在使用a类型的场合使用b类型时引发

敲“shift”键的麻烦
4. 分号主要是给机器看的,但 Python 更注重于人性化。早期硬件有所限制,加分号可以提升解析/编译的速度,但如今障碍已除,某些分号党语言只是在延续 B/C 语言的老传统
5. 对于需要换行的语句,Python 中使用反斜杠(\)来连接,可以理解成它把换行给转义了,能够解决一句多行的问题

打印出菱形

for i in range(4):
    for j in range(2-i+1):
        print(" ",end="")
    for k in range(2*i+1):
        print("*",end="")
    print()
for i in range(3):
    for j in range(i + 1):
        print(" ",end="")
    for k in range(4 - 2 * i + 1):
        print("*",end="")
    print()
#打印菱形首先要想到每一行除了中间的星号外,要想到每一行第一个星号前面打印几个空格,从第一行往下依次减少一个空格到中间为止。在依次增加一个空格。然后打印星号需要依次打印,就要用到循环,可以使用for循环在配合range函数使用,然后再想出符号range函数中的参数。每一行打印完需要换行,没打印完要输出空字符。

利用递归方法求5!。

#方法1
def fact(j):
    sum = 0
    if j == 0:
        sum = 1
    else:
        sum = j * fact(j-1)
    return sum
print(fact(5))
#递归方法首先要想到函数然后定义一个函数在函数中使用递归方法,为了防止0*任何数都得零就要先把等于0得值转换成1,然后再定义一个依次减一得参数,并返回值。
#方法2
import math as ma
x = int(input())
print(ma.factorial(x))
#factorial求所有函数的阶乘

按逗号分隔列表。

o = [1,2,3,4,5]
s1 = ','.join(str(n) for n in o)
print(s1)
#join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。

从100个数中随机生成10个数

#方法1
import random
for i in range(1,11):
    print(random.randint(1,101))
#方法2使用列表方法
import random
x = []
for i in range(1,11):
    x.append(random.randint(1,101))
    print(x)
#方法3使用sample函数
import random
num = range(1,101)
nums = random.sample(num,10)
print(nums)
#sample(序列a,n)从序列a中随机抽取n个元素,并将n个元素以list形式返回

错误与异常

概述

SyntaxError:发生语法错误时引发

FileNotFoundError:未找到指定文件或目录时引发

NameError:找不到指定名称的变量时引发

ZeroDivisionError:除数为0时的异常

IndexError:当使用超出列表范围的索引时引发

KeyError:当使用映射不存在的键时引发

AttributeError:当尝试访问未知对象属性时引发

TypeError:当试图在使用a类型的场合使用b类型时引发

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值