python入门笔记(掌握一门语言的四分之一)

基础

字符串

import keyword
from operator import index

print(123)  # 输出整型数值
print(12.3)  # 输出浮点型数值
print(0x1011)  # 输出16进制转化为十进制
print(0b1011)  # 输出2进制转化为十进制
print(3 + 4)  # 输出含有运算符的十进制
print("string")  # 输出字符串
print('helloworld')  # 输出字符串
print('hello\rworld(over)')#回车覆盖
print(ord('家'))     #返回字符码

字符串的驻留机制

'''字符串为不可变字符序列,不同的字符串存放在字符串的驻留池中
    相同的字符串只保留一份拷贝,后续创建相同的字符串不会开辟新空间,而是直接引用同一个地址'''
a='python'
b="python"
c='''python'''
print(id(a))
print(id(b))
print(id(c))
'''交互模式下(cmd_python),的驻留情况
    1、字符串长度为0或1
    2、符合标识符(下划线,字母,数字的组合)的字符串
    3、只在编译时驻留,而非运行时
    4、-5到256之间的整数'''
第三种情况:
a='abc'
b='ab'+'c'
c=''.join(['ab','c'])
print(a is b)
print(a is c)       #False 因为c的值是在运行时候赋值的,而非编译
a=-6
b=-6
print(a is b)       #在交互式环境下显示False
强制指向同一个空间
import sys
a='abc%'
b='abc%'
print(a is b)

在交互模式下运行结果

字符串的查询操作

a='Hello,Hello'
print(a.index('lo'))    #3,第一次出现的位置,不存在抛出ValueError
print(a.find('lo'))     #3,第一次出现的位置,不存在返回-1
print(a.rfind('lo'))    #9,最后一次出现的位置,不存在返回-1
print(a.rindex('lo'))   #9,最后一次出现的位置,不存在抛出ValueError

大小写转换方法

'''s.upper()    所有变大写
   s.lower()    所有变小写
   s.swapcase() 大写变小写,小写变大写
   s.capitalise()首字符字母大写,其他小写
   s.title()    每个单词第一个字母大写'''
print(a.upper())        #HELLO,HELLO
print(a.lower())        #hello,hello
print(a.swapcase())     #hELLO,hELLO
print(a.capitalize())   #Hello,hello
print(a.title())        #Hello,Hello

字符串内容对齐操作

'''s.center()   居中对齐,参数1:宽度,参数2:填充符(默认空格),设置宽度小于实际宽度,返回原字符串
   s.ljust()    左对齐,参数1:宽度,参数2:填充符(默认空格),设置宽度小于实际宽度,返回原字符串
   s.rjust()    右对齐,参数1:宽度,参数2:填充符(默认空格),设置宽度小于实际宽度,返回原字符串
   s.zfill()    右对齐,左边用0填充,参数:字符串宽度,小于等于字符串宽度,返回字符串本身'''
s='hello*world*python'
print(s.center(20,'*'))
print(s.ljust(20,'*'))
print(s.rjust(20,'*'))
print(s.zfill(20))
print(s.zfill(8))

劈分操作

'''s.split()    从字符串左边开始劈分,默认劈分字符为空格,经过最大次劈分后,剩下的子式单独作为一部分。返回列表,参数:劈分符,最大劈分次数
   s.rsplit()   从字符串右边开始劈分,默认劈分字符为空格,经过最大次劈分后,剩下的子式单独作为一部分。返回列表,参数:劈分符,最大劈分次数'''
print(s.split('*',1 ))   #分割不同的单词

判断字符串操作

'''s.isidentifier() 判断字符串是不是合法标识符
   s.isspace()      判断字符串是不是全部由空白字符(空格换行水平制表符)组成
   s.isalpha()      判断字符串是不是全部由字母组成
   s.isdecimal()    判断字符串是不是全部由十进制数字组成
   s.isnumeric()    判断字符串是不是全部由数字组成
   s.isalnum()      判断字符串是不是全部由字母和数字组成'''
print('张三_123'.isidentifier())  #True
print('张三'.isalpha())           #True
'''除了阿拉伯数字以外,其他isdicimal()方法都是False
   isnumeric()方法中,1二Ⅲ④都是数字'''
print('④'.isnumeric())

字符串的替换和合并

'''s.replase()  参数:被替换的子串,替换成的字符,最大替换次数。
   s.join()     列表或元组的字符串合并成一个字符串'''
s=['hello','python','world']
print('*'.join(s))
print('*'.join('python'))
s='小白兔白又白两只耳朵竖起来'
print('了'.join(s))

字符串的比较

'''运算符:> < >= <= == !=
    比较规则:先比较第一个字符,如果相等,继续比较。。。
    比较原理:比较的是字符的原始值,调用内置函数ord()可以得到指定字符的原始值
            chr()是ord()的互相对应函数,chr()函数可以用原始值得到字符'''
a='apple'
b='app'
print(a > b)
print(ord('a'),chr(ord('l')))

比较:is 和 ==

#==:值相等,    is:id相等

字符串的切片操作:将产生新的字符串

print(id(a))
a=a[:2]
print(a,'\t',id(a)) #a重新分配地址

格式化字符串 % 占位符

name='ming'
age=20
print('我叫%s,今年%d岁' % (name,age))
#{}占位符
print('我叫{0},今年{1}岁'.format(name,age))
#f-string
print(f'我叫{name},今年{age}岁')

精度和宽度

'''% num.int f: num表述宽度(宽度不够左边补空格),int表示精度(保留几位小数)'''
print('{0:.3}'.format(3.141592654))     #0表示索引(可省略),3表示保留3位数
print('{0:10.3f}'.format(3.141592654))    #3f表示保留三位小数,10表示宽度

字符串的编码转换

'''编码:将字符串转化成二进制数字'''
a='唧唧复唧唧'
print(a.encode(encoding='GBK')) #GBK:国标扩展,编码格式,一个中文占两个字节
print(a.encode(encoding='UTF-8'))   #一个字节占三个字节
byte=a.encode(encoding='GBK')
print(byte.decode(encoding='GBK'))  #解码

数据输出到文件中

  • 关键字列表
fp=open('D:/text.txt', 'a+')  # 函数open(‘路径’,‘打开方式(读写)’)
#print(keyword.kwlist,file=fp)   #输出
fp.close()

变量

  • 变量不需要定义类型
name='张三' \
     '李四'
print(name)
print(name[0])      #字符串自动带入为数组
number=0x123        #十进制:291
print(number)

#print(number[0])   #报错,因为这里自动定义为int型号
number_string='123'
print(number_string[0],number_string[1])
number='一二三'
print(number)       #变量迭代过程:删除原内存,重新分配空间并且重新更改新的数据类型
number=True         #布尔类型区分大小True/False
print(number,'\n',type(number))

进制

#二进制:0b,     8进制:0o      十六进制:0x
#浮点数偏差
n1=1.1
n2=2.2
print(n1+n2)        #输出结果3.3000000000000003

from decimal import Decimal
print(Decimal(n1)+Decimal(n2))      #输出3.300000000000000266453525910
print(Decimal('1.1')+Decimal('2.2'))    #输出3.3

利用三引号进行连续输出

print('''小时候总想长大
长大后总想变小
时间赋予我们意义''')

数据类型转换

print(len(number_string))
age=21
# print('我叫'+name+‘今年’+age)  不能同类型输出流
print('我叫',name[0], name[1],'今年',age,'岁')    #这样可以
print('我叫' + name[0] +name[1] + '今年' + str(age) + '岁')
'''嘿嘿嘿我是多行注释
嘿嘿嘿'''
#规则:文字类和小数string不能转换为int,文字类不能转换为float

输入函数

dinner = input('晚饭吃了啥?')
print(dinner)
a=input('请输入第一个数')
b=input('请输入第二个数')
print('a+b=' ,a + b)             #输出12 13,并没有进行运算
print(type(a),type(b))   #输入类型自动定为string类
'''a=int(a)
b=int(b)'''
#或者在输入行中转换:a=int(input(''))
print('a+b=', a + b)

运算符

  • 普通运算符
print(11/2)    #直接输出浮点数
print(11//2)   #整除运算符
print(11%2)    #取余数
print(2**4)    #次方运算
  • 赋值运算符:从右往左,所有编译器默认
a=b=c=3        #链式赋值
print(id(a),id(b),id(c))      #地址相同,相当于引用同一个参数
'''语言特性:免除参数类型定义的过程,底层将自动为变量取类型'''
a+=20
print(a,type(a))
a-=3
print(a,type(a))
a*=2
print(a,type(a))
a/=3
print(a,type(a))
a//=2
print(a,type(a))
'''以上运算,输出结果为
23 <class 'int'>
20 <class 'int'>
40 <class 'int'>
13.333333333333334 <class 'float'>
6.0 <class 'float'>'''

解包赋值

a,b,c=20,10,50
print(a,b,c)        #左右相对应数量
  • 利用此语言特性进行数值交换
a,b=b,a
print(a,b)
#对象id对比
print('a 和 b是同一个对象吗',a is b)  #False
print(id(a),id(b))
print(a is not b)        #True

逻辑运算符

'''与或非分别对应:and or not'''
a=True
print(not a)

'''目标是否在某个对象内部:in , not in'''
print('================================')
s='windows'
print('w' in s)
print('s' not in s)
print('============位运算===============')
'''位的与或和位移:  &|  >>and<<
位移: 左移:高位溢出,低位补零
      右移,高位补零,低位截至
    优先级:方,乘除,位移,位逻辑,比较,逻辑(布尔),赋值
python 每一个对象都有一个布尔值
以下对象布尔值为False:
False\数值0\ None\空字符串\空列表\空元组\空字典\空集合   取布尔值函数:bool()'''
#print(bool(False))          #False
print(bool(0),bool(0.0))    #数值0
print(bool(None))           #None
print(bool(''))             #空串
print(bool(""))             #空串
print(bool([]))             #空串
print(bool(list()))         #空列表
print(bool(()))             #空列表
print(bool(tuple()))        #空元组
print((bool({})))           #空元组
print(bool(dict()))         #空字典
print(bool(set()))          #空集合

静态语言和动态语言多态的区别:

'''继承
   方法重写
   父类指向字类对象
   python是动态语言
'''

分支循环

if else

'''语法结构:if 语句:
    else:'''
num=int(input('请输入一个整数'))
if num%2==0:
    print('偶数')
else:
    print('奇数')
print('========多分支if elif=========')
if num>=90 and num<=100:
    print('A')
elif num>=80 and num<=90:
    print('B')
elif num>=70 and num<=80:
    print(('C'))
else:
    print('成绩有误')
'''语言特性:连续判断'''
if 90<=num<=100:
    print('A')
elif 80<=num<=90:
    print('B')
elif 70<=num<=60:
    print('C')
elif 60<=num<=50:
    print('D')
elif num<=60:
    print('E')
else:
    print('成绩有误')
'''判断表达语法优化'''
a=int(input('请输入第一个数值'))
b=int(input('请输入第二个数值'))
print( (a,'大于等于',b)  if a>=b else (a,'小于等于',b))

range序列

r=range(10)     #生成10个元素的序列,起头默认为0,步长默认为1
print(list(r))
r=range(0,10)   #range(start,stop)前闭后开区间,步长1
print(list(r))
r=range(0,20,2) #range(start,stop,step):前闭后开
print(list(r))
print(10 in r)

print('============循环============')
'''while 条件:
    循环体'''
a=1
while a<10:
    print(a)
    a+=1        #python中没有a++

  • python中的求和函数
a=range(0,101,2)
print(sum(a))
print('=========================')
summ=0
a=1
while a<=100:       #嵌套分支
    if not a%2:
        summ+=a
    a+=1
print(summ)         #输出同样结果

for in 遍历对象

'''for 对象 in 遍历元素'''
for item in "Python":       #”“和’‘都代表同一个数据(对象)类型
    print(item)
print(item)         #此处的对象创建为只有一个元素的字符数组
'''
a=0
for item1[a] in 'Python':
    a+=1
print(a)
'''
#不允许以上运行,在当前库中for in仅允许创建的对象为一个元素
for i in range(11):
    print(i)
print(i)
  • 如循环中,不需要用到自定义变量,可用下划线_代替自定义变量
for _ in range(5):      #输出5次hello
    print('hello')

break 跳出循环

for _ in range(1):          #注意缩进格式
    psw=input('请输入密码:')
    if psw=='8888':
        print('密码正确')
        break
    else:
        print('密码不正确')

continue 语句实现循环控制

'''continue和pass区别,
continue:跳过本次循环,不论下面有多少语句
break: 跳出循环
pass: 只起到占位作用,后面的语句回继续执行'''
for _ in range(1):
    pwd=input('请输入密码:')
    if pwd!='8888':
        print('密码不正确')
        continue
    else:
        print('密码正确')
  • #循环else语句:循环中没有遇到break语句时候执行else(循环中,没有遇到break认为非正常退出,返回False,触发执行else中语句
    for _ in range(2):
        pwd=input('请输入密码:')
        if pwd=='8888':
            print('密码正确')
            break
        else:
            print('密码不正确')
    else:
        print('输入两次密码错误')
    

嵌套循环

for i in range(4): #4行
    for j in range(i+1):        #range()中i初始值为0时,直接跳出该循环
        print('*',end='\t')    #为末尾end传递一个空字符串,实现不换行输出
print('')

数据结构

列表

# 可以存储多个元素,相当于数组,但更加具有包容性,不需数组内部元素为同一种类型
a=10        #变量:一个对象的引用
lst=['hello' , 12 , 13.5]
print(type(list[0]) , type(list[1]) , type(list[2]))
'''输出结果:<class 'types.GenericAlias'> <class 'types.GenericAlias'> <class 'types.GenericAlias'>显示数据类型为
‘通用型’
list内部存储的为引用'''

列表创建的两个方法

# 方括号 和 内置函数list()
lst=[1,2,3]
lst2=list([1,2,3])
print(lst , lst2)
#特性:顺序存放,空间连续,索引映射可以为负数,根据需要动态分配内存
print(lst[-1],lst[-3])

获取索引内置函数index

print(lst.index(2))     #排序为0开始 0123456789
lst=['hello','world',56,'hello','12',58,'strike']
print(lst.index('hello',1,4))   #从索引为1到4之间(左闭右开区间)寻找‘hello’,程序报错,找不到

切片操作

print(lst[0:6:2])       #lst[start:stop:step]左闭右开  , 默认start为0,stop为最后一个元素(包括),步长为1
                        #step为负数切片默认第一个元素为最后一个元素,最后一个元素为第一个元素

列表元素的遍历:for in

for item in lst:
    print(item,end=', ')
print()
print(item)

添加元素

'''append()在末尾添加,extend()在末尾添加至少一个元素,insert()在列表插入一个元素'''
lst.append(100)
print(lst)
lst2=[10, 20 ,30 ,40 ,8.5]
lst.extend(lst2)
print(lst)
lst.insert(2,90)        #在索引为2的位置添加一个元素90,原本在2的元素后移
print(lst)      #输出['hello', 'world', 90, 56, 'hello', '12', 58, 'strike', 100, 10, 20, 30, 40, 8.5]

剪切操作

lst[1:]=lst2    #将后面的元素替换
print(lst)      #输出['hello', 10, 20, 30, 40, 8.5]
lst[1:1]=lst2   #不剪切其他元素
print(lst)      #输出['hello', 10, 20, 30, 40, 8.5, 10, 20, 30, 40, 8.5]
lst[-2:-3]=lst2 #在-2到-3之间插入元素,不覆盖,不删除(不论stop在何处,都是一样的结果)
print(lst)
print(id(lst))
lst[-3:]=lst2   #在-3处插入覆盖包括-3
print(lst)
print(id(lst))

删除列表中元素

lst=[10, 20, 30, 40, 50, 60, 99,  'python']
lst.remove('python')    #删除一个元素,重复发元素只删除第一个
print(lst)
lst.pop(1)              #删除索引为1的元素
lst.pop()               #删除最后一个元素
#此时lst为:[10, 30, 40, 50, 60]

切片删除,产生新的列表对象

new_lst=lst[1:4]        #左闭右开
print(new_lst)
print(lst)
print(id(lst),id(new_lst))  #原lst被分配到一个新的空间,lst:1763910987712 ,new_lst:1763910987648

切片删除,不产生新列表

lst[1:3]=[]
print(lst,id(lst))
lst.clear()                 #清楚列表的所有元素
print(lst)                  #输出空列表,列表所在空间并未删除
del lst                     #将列表空间清除内存
del lst2
del new_lst
#print(lst)                 #报错,lst未定义:NameError: name 'lst' is not defined

lst=[10, 20, 30, 40, 50, 99]

修改值

lst[5]=60
print(lst)
lst[1:3]=[200, 300, 400, 500]   #将索引为1到3的元素(左闭右开)替换
print(lst)

sort()方法

lst=[85,62,43,29,995,35,615,24,32,2]
print('排序前:', lst, id(lst))
lst.sort()
print('排序后列表:', lst, id(lst))   #列表对象没有改变
lst.sort(reverse=True)              #降序
print(lst)

内置函数 sorted()

lst=[85,62,43,29,995,35,615,24,32,2]
new_lst=sorted(lst)
print(new_lst, id(new_lst))
new_lst=sorted(lst,reverse=True)
print(new_lst,id(new_lst))          #两个new_lst对象都是新的引用

生成列表方法

lst=[i for i in range(1,10)]

字典

字典创建的两种方式

# 无序序列,双射集合:key->value,可变序列
scr={'ming':100, 'hong':95, 'gang':86}
print(scr)
print(type(scr))
student=dict(name='jac',age=22)
print(student)
  • 空字典
    scr={}
    

字典元素的操作

  • 字典元素的获取
scr={'ming':100, 'hong':95, 'gang':86}
print(scr['gang'])
print(scr.get('ming'))      #字典的get方法,如果元素不存在,程序不会报错,方法返回None
print(scr.get('qiang', 404))  #当元素不存在,返回默认值为404(可以为其他数值)
#字典的判断:in 和 not in

字典的删除

del scr['gang']
print(scr)
scr.clear()                 #清空字典元素
print(scr)
scr['chen']=100
print(scr)
scr['chen']=96               #修改操作

获取视图

print('===================')
scr={'ming':100, 'hong':95, 'gang':86}
ky=scr.keys()
print(ky, '\t \t', type(ky))         #dict_keys(['ming', 'hong', 'gang']) <class 'dict_keys'>
vilus=scr.values()
print(vilus, '\t \t',type(vilus))
i=scr.items()               #取出元组
print(i)
print(list(i))              #转换为元组列表输出

字典元素的遍历

for item in scr:
    print(item,scr[item],scr.get(item))
print(item)                 #遍历基于关键字,因此这里for in 是基于关键字的值

字典关键词不允许重复赋值

scr={'name':'gang', 'name':'ming'}
print(scr)                  #赋值覆盖  {'name': 'ming'}
#字典为无序的,d={lst:100} 报错,lst类型为不可哈希值,不可以哈希存储
#字典浪费大内存空间:空间换时间的数据类型,查找方便

字典生成

# 将两个列表的元素组合成为字典:内置函数zip()
nam =['hong', 'jac', 'lisa', 'peng', 'zhang']
age =[21,22,20,21,28]
student={nam.upper():age for nam, age in zip(nam, age)} #upper()方法为将字母大写
print(student)                  #如果元素不对称,只遍历最少存在部分
new_student={'HONG':21, 'JAC':22, 'LISA':22, 'ZHANG':19, 'TING':22}
student.update(new_student)     #更新操作:有新的变化就改变
print(student)
new_student=student.copy()      #浅拷贝
student.pop('PENG')             #单个删除
print(student)
num=dict.fromkeys([1,2,3],['one','two','three'])    #创建并且返回一个薪字典,前为key,后为value,默认value为None
print(num)                      #此处不能分别赋值
student.popitem()               #删除最后一个键和值
print(student)
print(student.setdefault('ZHANG',23))
'''第一个参数为key,如果key存在,返回该key对应的value,否则将key插入字典并将其value设为函数给定值,默认值为None'''
print(student.setdefault('kiven'))
print(student)                  #{'HONG': 21, 'JAC': 22, 'LISA': 22, 'ZHANG': 19, 'kiven': None}
print(student.__len__())        #返回字典key数量的多少

元组

'''可变序列: 列表 字典:可以增删改
   不可变序列: 字符串 元组 改变内容之后地址改变'''
t=('python', 56, 12.8)
print(t, type(t))
t1=tuple(('hello', 'world', 98))    #两个括号
print(t1)
t2='python','hello','world'
print(t2)
t3='hello',
print(t3,type(t3))                  #如果元组只含有一个元素,需要用逗号(小括号可以删除)
  • 空元组
    t4=()
    print(type(t4))
    

元组的特性:只可读性,元组存储的对象不可改变

'''如果元组对象本身不可对象(数值,str。。。),则不可以再引用其他对象
   如果元组中对象是可变对象(dict,list),则可改变对象的引用不许改变(如lst时,不可将元组中的引用地址改变),
   但数据可以改变(如引用对象为lst,那么可以对这个lst进行增删改)'''
t=(10,[10,20,30],99)
print(t)
#t[0]=1     #报错,元组对象不可修改
t[1].append(40)                     #可以修改可变对象的数据
print(t)
#元组的for in 遍历
for item in t:
print(item)                     #可读

集合

集合的创建

# 可变数据类型:没有value(只有键)的字典(哈希取址)
s={2,3,4,5,5,6,7,7,5}
print(s)        #不重复性
s2=set(range(6))
print(s2,type(s2))
s3=set([2,1,3,6,6,6,8,7,5,4])
print(s3,type(s3))      #将列表转换成集合
s4=set((1,2,3,56,86,3,2,5,))
print(s4,type(s4))      #元组转换:元组储存无序
s5=set('python')
print(s5)               #无序
  • 空集合的定义方法
#s6={}          不行,定义类型为空字典
s6=set()
print(type(s6))
  • in 和 not in判断集合元素

集合的增加元素操作

s6.add(1)
print(s6)
s6.update({200,'p'})      #需要花括号
print(s6)
s6.update(['y',200,1,3])
print(s6)                   #重复元素不添加

删除操作

s6.remove(200)
s6.discard('p')              #没有该成员忽略,有此成员删除
print(s6)
s6.pop()                #任意删除,不能添加参数
print(s6)
s6.clear()
print(s6)               #清除
s1={1,2,3,4}
s2={3,2,1,4}
s3={12,3,1,2,4,5,6,7,8,9}
print(s1==s2)           #只判断元素

子集判断

print(s3.issubset(s1))  #s3不是s1子集
print(s1.issubset(s3))  #s1是s3子集

超集判断

print(s3.issuperset(s1))

是否有交集判断

print(s3.isdisjoint(s1))    #没有交集是True

集合的数学操作

  • 交集
print(s1.intersection(s3))
print(s1 & s3)
  • 并集
print(s1.union(s3))
print(s1 | s3)
  • 差集
print(s3.difference(s1))
print(s3-s1)
  • 对称差
print(s1.symmetric_difference(s3))
print(s1 ^ s3)

集合生成式

s3={ i*i for i in range(10)}
print(s3)           #无序

数据结构

函数

函数的定义

def sum(a=0, b=0, str='function called'):
    c=a+b
    print(str)
    return c
print(sum(10 ,20))
print(sum())
print(sum(str='hello',b=10,a=6))    #参数的指向赋值

函数调用参数的方式

# 调用引用
def fun(a=0, b=[0,0,0]):
    print('a=',a,'id of a:',id(a))
    print('b=',b,'id of b:',id(b))
    a=100                   #此时a的引用对象id改变
    b.append(10)
    print('a=',a,'id of a:',id(a))
    print('b=',b,'id of b:',id(b))
    b=[1,2,3,4]
    print(b,id(b))          #b的id也发生了改变,此时b不再是n2的引用,而是新对象:列表[1,2,3,4]的引用
n1=11
n2=[11,22,33,44]
print('id n1:',id(n1))
print('id n2',id(n2))
fun(n1,n2)
print('n1:',n1,id(n1))
print('n2:',n2,id(n2))     #调用对象是一个指针,对指针地址不产生影响,但可以对指针所指的对象进行数据的修改
'''底层:对a进行赋值改变时,a引用的对象的指针将改变,并不影响原来n1的数值,n1一直都是原来数值的引用
   参数传递过程:将不可变对象传进函数时,形参等于原对象的另一个引用,当函数过程中对形参进行改变时,底层分配一个新的对象
   给形参,此时形参变成新对象的引用,原参数依然是原对象的引用'''

函数的返回

'''
    1.没有返回值,可以忽略return,返回None
    2.返回值只有一个,直接返回类型
    3.返回值多个,返回元组
'''
def fun1():
    print('hello')
print(fun1())

函数的参数定义

'''
    个数可变的位置参数
        定义函数无法确定传递的实参数量多少
        使用*定义个数可变的位置形参
        结果为一个元组
    个数可变的关键字形参
        定义函数无法确定传递的关键字实参个数
        使用**定义个数可变的关键字形参
        结果为一个字典
    【注】:以上的两种参数只能是一个
'''
def fun_a(*args):
    print(args)
fun_a(10,20,30)
def fun_b(**kwargs):
    print(kwargs)
fun_b(a=10)
fun_b(a=10, b=20, c=30)
def fun_c(*args,**kwargs):
    pass
'''
def fun_d(**kwargs,*args):
    pass        #报错,在函数定义过程中,既有个数可变的关键字形参,也有个数可变的位置形参
                 要求*args在**kwargs之前
'''

函数的调用

def fun_1(a,b,c):   #函数调用时的参数传递,为位置传参
    print(a,b,c)
lst=[11,22,33]
fun_1(*lst)         #将列表中的每个元素转换成位置实参传入,lst中元素不可以大于参数个数
dic={'c':111,'a':222,'b':333}
fun_1(**dic)        #将字典的value传入,其中不比较关键字的值,只按照位置传递
print('============')
def fun_2(a,b,*,c,d):   #在*后的参数只能采用关键字实参传递
    print(a)
    print(b)
    print(c)
    print(d)
#fun_2(2,3,4,5)         #报错
fun_2(2,3,c=4,d=5)
#以下几种顺序
def fun_3(a,b,*,c,**kwargs):
    pass
def fun_4(a,b,*args,**kwargs):
    pass
#def fun_5(a,*,b,c,*args):      #报错
#    pass

递归函数

def fun_revs(a):
    if a-1:
        return a+fun_revs(a-1)
    else :
        return a
print(fun_revs(5))

递归的应用:斐波那契数列

def fbnq(a):
    if a==1:
        return 1
    elif a==2:
        return 1
    else:
        return fbnq(a-1)+fbnq(a-2)
print(fbnq(6))

输出数列

for i in range(1,7):
print(fbnq(i),end=' ')

调试

  • 被动bug的异常处理

try except 语句

try:
    a=int(input('请输入第一个数:'))
    b=int(input('请输入第二个数'))
    result=a/b
except BaseException as e:
    print('错误:',e)
else:
    result
    print('结果:',result)
finally:
    print('无论是否产生异常,总会执行的语句')
    print('谢谢你的使用')
print('程序结束')
'''常见异常类型
    ZeorDivisionError   除0
    IndexError          序列中没此索引
    KeyError            映射中没有这个键位
    NameError           未声明/初始化对象(没有属性)
    SyntaxError         Python语法错误
ValueError          传入无效参数
'''

traceback模块打印异常信息

import traceback
try:
    raise Exception('i\'m obviously an error')    #自行引发异常
except Exception as reason:
    print('错误类型:',reason)
#raise Exception('i\'m obviously an error')       #报错,Exception:i'm obviously an error

print(dir([]))      #dir查看模块列表
print(dir())        #dir()获得当前模块的属性列表
a=10
print(a.__sizeof__())   #对象的sizeof方法下

'''
if __name__=='__main__':
    try:
        1/0
    except Exception as e:
        traceback.print_exc()   #得到具体的错误,以及定位到出错的位置
'''
#调试使用Shift+F9

类的创建

class Student:                  #规范:首字母大写
    location='广东'                       #共有属性(修改共享化)
    def __init__(self,name,age):        #等于C++中的构造函数
        self.name=name                  #私有属性(修改私有化,不共享)
        self.age=age
    def info(self):                     #实例方法
        print('我的名字是:',self.name,'年龄:',self.age)    #self是自身对象,相当于this指针
    def eat(self):
        print(self.name,'是干饭王')
    @classmethod
    def fun1(cls):
        print('类方法')
    @staticmethod                       #使用stativmethod
    def fun2():
        print('静态方法')
print(id(Student))
print(type(Student))
print(Student)

类指针

创建对象的方法

n3=Name_class('zhang',10)
print('id of obj:n3 is :{0}'.format(id(n3)))    #反映出self就是n3
n4=Name_class.__new__(Name_class,'zgr',56)      #和n3=Name_class('zhang',10)相同
stu1=Student('zhang',20)        #自动调用构造函数构建
print(id(stu1))
print(type(stu1))
Student.eat(stu1)
stu1.eat()

类的属性、方法

    '''
    类属性:除方法之外的变量,被所有类共享
    实例方法:被实例对象调用
    类方法:使用类名直接访问的方法
    静态方法:使用类名直接访问
    类中定义了同名的方法时,调用方法会执行最后定义的方法

    静态方法和类方法的区别
    1、类方法:
        用修饰器@classmethod来标识其为类方法,类方法第一个参数必须是类对象,一般以cls作为第一个参数
    2、静态方法:
        需要通过装饰器@staticmethod来进行修饰
        静态方法既不需要传递类对象也不需要传递实例对象(形参没有self/cls,参数没有要求)。
        静态方法也能够通过实例对象和类对象去访问。
        无视self,而将这个方法当成一个普通的函数使用。
    使用场景:
    当方法中 既不需要使用实例对象(如实例对象,实例属性),也不需要使用类对象 (如类属性、类方法、创建实例等)时,定义静态方法
    取消不需要的参数传递,有利于减少不必要的内存占用和性能消耗

    1、通过实例定义的变量只能被实例方法访问
    2、而直接在类中定义的静态变量(如本例的xy变量)可以被实例方法访问,也可以被静态方法和类方法访问。
    3、实例方法不能被静态方法和类方法访问,但静态方法和类方法可以被实例方法访问。
    下面的代码,静态方法调用另一个静态方法,如果改用类方法调用静态方法,可以让cls代替类,
    让代码看起来精简一些。也防止类名修改了,不用在类定义中修改原来的类名。

    从下面代码可以看出,如果子类继承父类的方法,子类覆盖了父类的静态方法,
    子类的实例继承了父类的static_method静态方法,调用该方法,还是调用的父类的方法和类属性。
    子类的实例继承了父类的class_method类方法,调用该方法,调用的是子类的方法和子类的类属性。'''

class Zz(object):
    x=1                 #静态变量
    y=2

    def __init__(self,a=3,b=4):
        self.a=a
        self.b=b

    def aa(self):
        return self.a+self.b

    @staticmethod
    def averag(*args):
        return sum(args)

    @staticmethod
    def static_method():
        print('静态方法中调用静态方法')
        #return Zz.averag(Zz.a,Zz.b)    #报错,未声明a,b
        return Zz.x+Zz.y                #只能使用类的参数,不能使用实例中定义的参数(对象的参数)

    @classmethod
    def class_method(cls):
        print('在类方法中使用类方法')
        return cls.averag(cls.x,cls.y)

   # @staticmethod              #报错,实例方法只能被对象访问
   # def static_method1():
   #     return Zz.aa()

class SonOfZz(Zz):
    x = 11
    y = 22

    @staticmethod
    def averag(*args):
        print('子类的静态方法重载')
        return sum(args)/2.5

f=Zz(11,22)
print(f.averag())
print(f.class_method())
print(f.static_method())
#print(f.static_method1())
print('====================')
s=SonOfZz()
print(s.static_method())      #子类的实例继承了父类的static_method静态方法,调用该方法,还是调用的父类的方法和类属性。
print(s.class_method())       #子类的实例继承了父类的class_method类方法,调用该方法,调用的是子类的方法和子类的类属性。

类对象的指针概念

'''类的对象有类指针概念,指向类(在python中,一切皆对象,类也是一种对象)'''
stu1.location='天津'
stu1.name='ling'
print(stu1.location)    #对类里面的共享变量直接修改
print(stu1.name)

动态绑定属性,在类中直接添加新属性和新方法

stu1.gender='女'         #动态绑定属性
def fun(a=0):
    print('我是一个函数',a)
stu1.fun=fun
stu1.fun()
  • 面对对象的三个特性:
    • 封装:将属性和方法封装到类对象中。在方法内部实现对属性的操作,在类对象的的外部调用方法。
      这样,无需关心方法内部的具体实现细节,从而隔离了复杂度
    • 继承:提高代码的复用性
    • 多态:提高程序的可扩展性和可维护性
class Car:
    def __init__(self,brand,macid):
        self.brand=brand
        self.__macid=macid      #‘__’表示不希望在类的外部被使用(私有属性)
    def showmemac(self):
        print(self.__macid)
aodi=Car('奥迪', 4562531)
aodi.showmemac()
#print(aodi.macid)              #报错,不可直接外部使用
print(dir(aodi))
print(aodi._Car__macid)         #通过此方法也可访问私有属性

继承

单继承

#(支持多继承),如果一个类没有继承,默认继承object类,定义子类时,必须在其构造函数中调用父类的构造函数
class Person(object):
    def __init__(self,name,age):
        self.__name=name
        self.age=age
    def info_name(self):
        print(self.__name,end=' ')
    def info_oth(self):
        print(self.age,end=' ')
    def __str__(self):
        return '姓名:'+self.__name+' 年龄:'+str(self.age)   #返回对象只能是一个,否则返回元组不是str类型,
                                                            #用+返回时候需要对非str类型进行转换
        #或者用
        #return '姓名:{0},年龄:{1}'.format(self.__name,self.age)

class Male(Person):
    def __init__(self,name,age,gender):
        super(Male, self).__init__(name,age)
        self.gender=gender
    def pr_gen(self):
        print(self.gender)
#zhang_s=Male('zhangsan',21,'mals')
#zhang_f=Male('zhangba',51,'mals')
#print(zhang_f.name)        #报错
#zhang_f.info()
#zhang_s.pr_gen()

多继承

class A(object):
    def __init__(self,a,d):
        self.a=a
        self.d=d
class B(object):
    def __init__(self,b):
        self.b=b

class C(A,B):
    def __init__(self,a,b,c,d):
        super(C, self).__init__(a,d)  #效果等同于A.__init__(self,a)
        #super() 函数只可用于调用第一个父类的构造函数,其余父类的构造函数只能使用未绑定的方式调用
        B.__init__(self,b)
        self.c=c

c_oj=C(1,2,3,4)
print(c_oj.a,c_oj.b,c_oj.c,c_oj.d)
#考虑到多层继承的问题,优先使用super()而不是使用未绑定的方法调用构造函数

‘’’
1.父类的非私有属性和非私有方法子类可以直接继承,子类对象可以直接使用。
如果子类要调用父类的私有属性和私有方法,只能通过间接的方法来获取。

2.子类可以实现父类没有的属性和方法,与继承的属性和方法互不干扰。

3.如果在子类中有跟父类同名的方法,但方法中执行的内容不同,则子类可以重写父类方法。
当子类实现一个和父类同名的方法时,叫做重写父类方法。直接在子类中定义与父类同名的方法,
然后在方法中实现子类的业务逻辑,子类方法就会覆盖父类的同名方法。子类重写了父类方法,
子类再调用该方法将不会执行父类的方法。

4.如果在子类重写父类的方法中,需要使用父类同名方法中的功能,在父类功能基础上做扩展,
则子类可以在重写的方法中调用父类被重写的方法,使用super()来调用。’’’

子类方法重写(1)
class Teacher(Person,object):
    def __init__(self, name, age,techyear):
        super(Teacher, self).__init__(name,age)
        self.techyear=techyear
    def info_oth(self):             #对此方法进行重写
        print(self.age,self.techyear)
子类方法重写(2)
class Officer(Person,object):
    def __init__(self, name, age,ofisyear):
        super(Officer, self).__init__(name,age)
        self.ofisyear=ofisyear
    def info_oth(self):             #对此方法进行重写,使用上述笔记中4的方法
        super(Officer, self).info_oth()
        print(self.ofisyear)

t1=Teacher('wang',36,10)
t1.info_name()
t1.info_oth()

of1=Officer('bai',56,20)
of1.info_name()
of1.info_oth()

object类

'''
    所有类的父类,所有类都有object的属性和方法
    内置函数dir()可以查看指定对象的所有属性
    object有一个__str__()方法,用于返回一个对于[对象的描述]
        对应于内置函数str()经常用于print()方法,帮我们查看
        对象的信息,所以我们经常会对__str__()进行重写
'''
print(of1)  #对__str__()方法重写后可以很好用于输出
print('==========')
print(c_oj)   #不重写,返回地址
print(dir(of1))
#多态性:即使不知道一个变量所引用的对象的类型,仍然可以通过这个变量调用方法,在运行过程中,根据对象的类型
#       动态决定调用哪个对象中的方法

class Animal(object):
    def eat(self):
        print('动物需要能量')

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

class Human(Animal):
    def eat(self):
        print('人吃五谷')

def fun(annimal):
    annimal.eat()

def fun1(person):
    person.info_name()

fun(Dog())
fun1(Teacher('ling',36,14)) #如果类需要初始化参数,必须给出,否则报错
print('')
fun1(Person('wang',16))

特殊方法和特殊属性

'''
特殊属性:_dict_:获得类对象或实例对象所绑定的所有属性和方法的字典
特殊方法:__len__():重写__len__()方法,让内置函数len()的参数可以是自定义类型
        __add__():重写__add__()方法,可以使用自定义对象具有的‘+’功能
        __new__():用于创建对象
        __init__():用于对创建对象进行初始化
'''
print(t1.__dict__)       #查看实例对象所绑定的所有属性和方法
print(Student.__dict__)  #查看类对象所绑定的所有属性和方法
print(of1.__class__)     #输出对象所属的类
print(C.__base__)        #父类类型的元素,优先输出第一个父类
print(C.__bases__)       #所有父类类型的元素
print(C.__mro__)         #类的层次结构
print(A.__subclasses__())#查看子类列表

a=10
b=20
d=a.__add__(b)  #等于a+b
print(d)

class Name_class(object):
    def __init__(self,name,age):
        self.name=name
        self.age=age
        print('init function called ,self id is:{0}'.format(id(self)))
    def __new__(cls, *args, **kwargs):
        print('new function called,id is :',id(cls))
        obj=super().__new__(cls)
        print('new object id is :{0}'.format(id(obj)))
        return obj
    def __add__(self, other):
        return self.name+other.name
    def __len__(self):
        return len(self.name)

n1=Name_class('张三',10)
n2=Name_class('李四',20)
print(n1+n2)    #重新定义对象的加法运算
a=[11,22,33]
print(len(a))   #输出列表长度
print(len(n1))  #重写返回长度的方法
print('id of class:object is :{0}'.format(id(object)))
print('id of class:Name_class is :{0}'.format(id(Name_class)))

类的浅拷贝和深拷贝

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

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

cpu1=CPU()
cpu2=cpu1       #浅拷贝
print(cpu1)
print(cpu2)     #两者的id相同,两个不同的变量只是同一个对象(值)的引用
disk1=Disk()
computer1=Computer(cpu1,disk1)
import copy
computer2=copy.copy(computer1)
print(computer1,computer1.cpu,computer1.disk)
print(computer2,computer2.cpu,computer2.disk)       #只有主对象进行了拷贝,子对象的空间还是一样的
computer3=copy.deepcopy(computer1)
print(computer3,computer3.cpu,computer3.disk)       #子对象也拷贝了

模块

import calc     
#如果报错,在目录中单击邮件,make directory as -source root
#创建一个模块:.py文件,名称不要和python自带的标准模块名称相同
#导入方式:import 模块名称 【as 别名】
#         from 模块名称 import 函数/变量/类
#以主程序形式运行,每一个模块的定义中都包括一个记录模块名称的变量__name__,程序可以检测该变量,以
#确定他们在哪个模块中执行。如果一个模块不是被导入到其他程序中执行,那么他可能在解释器的顶级模块中执行

顶级模块__name__变量的值为__mian__

if __name__ == '__main__':      #main回车
    print(calc.add(20,10))
print('===================')

python的包

  • 分层次的目录结构,将一组功能相近的模块组织在一个目录下
  • 包的作用:代码规范,避免模块名称冲突
  • 包和目录的区别:包含__init__.py文件的目录成为包,目录里通常不包含__init__.py文件
  • 包的导入:import 包名.模块名

创建

  • 创建一个新的文件夹new-python package,文件夹内部有__init__.py文件的叫包,否则叫目录

目录创建

  • new -> Derictory
import package1.moduleB as jsq  #jsq就是这个模块的别名,使得代码更加简短
print(jsq.add(10,100))

导入包的注意事项

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

查看包的所有信息

  • 按住CTRL点开模块
  • 查看包的内容

模块安装位置

  • 找到语句:exec_prefix =

urllib包中的request模块

import urllib.request as req
print(req.urlopen('http://www.baidu.com').read())

import schedule
import time
def job():
    print('haha')

schedule.every(3).seconds.do(job)   #每隔3秒执行一次函数
while True:
    schedule.run_pending()
time.sleep(1)
  • 【在另一个calc.py文件中】

    # -*- coding:utf-8 -*-
    def add(a,b):
        return a+b
    
    def div(a,b):
    return a/b
    
  • 【在另一个package1.moduleA模块中】

    # -*- coding:utf-8 -*-
    def add(a,b):
        return a+b
    
    def div(a,b):
    return a/b
    

编码格式和文件读写

编码格式:乱码问题

  • python的解释器使用的是Unicode(内存)
  • py文件在磁盘中使用UTF-8存储(外存)
  • 字符编码格式

修改编码格式

  • 在开头语句中加入’#encoding=gbk’

编码格式决定文件大小

文件读写原理:io操作

  • 操作流程:python操作文件、打开或新建文件、读写操作、关闭资源
  • 打开文件:file=open(filename [,mode(打开模式:读/写,默认只读),encoding(默认编码格式位gbk)])
  • readlines()返回列表

文件打开方式

  • with语句:自动调用enter和exit特殊方法

  • 自动管理上下文资源,不论什么原因跳出with块,都能确保文件正确关闭,以此来达到释放资源的目的,无论过程是否报错

    with open('a.txt','r') as file:
        print(file.read())
    
  • MyContentMgr实现了特殊方法enter和exit成为该类对象遵守了上下文管理器协议
    该类对象的实例对象被成为上下文管理器

    class MyContentMgr(object):
        def __enter__(self):
            print('enter方法被调用执行')
            return self
        def __exit__(self, exc_type, exc_val, exc_tb):
            print('exit方法被调用执行')
        def show(self):
            print('show方法被调用执行')
    

    上下文管理器

    文件打开模式
    文件对象的方法

目录操作

  • os模块是python的内置的与操作系统功能和文件系统相关的模块
    该模块中语句的执行结果通常与操作系统有关,在不同操作系统中运行,得到的结果不一样
  • os模块和os.path模块用于对目录或文件进行操作
    目录操作1
    path模块操作目录的相关函数

其他包的使用请看高级应用篇

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值