python基础之字符串、函数、BUG和异常类型介绍及类和对象详细笔记

字符串

1.字符串介绍

字符串在python中是基本数据类型,是一个不可变的字符序列

2.字符串的驻留机制

仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,Python的驻留机制对相同的字符串只保留 一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符串的地址赋给新创建的变量
驻留机制的几种情况(交互模式)

  • 字符串的长度为0或1时
  • 符合标识符的字符串
  • 字符串只在编译时进行驻留,而非运行时
  • [-5, 256]之间的整数数字

sys中的intern方法强制2个字符串指向同一个对象

PyCharm对字符串进行了优化处理

字符串驻留机制的优缺点

  • 当需要值相同的字符串时,可以直接从字符串池里拿来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串是比较印象性能的。
  • 在需要进行字符串拼接时建议使用str类型的join方法, 而非 + , 因为join()方法是先计算出所有字符中的长度,然后再拷贝,只new(创建)一次对象,效率要比使用“+”的效率高。

3.字符串的查询操作方法

index() 查找子串substr第一次出现的位置,如果查找的子串不存在时,则抛出ValueError

s='hello,hello'
print(s.index('lo'))	#输出3

rindex() 查找子串substr最后一次出现的位置,如果查找的子串不存在时,则抛出ValueError

s='hello,hello'
print(s.rindex('lo'))	#输出9

find() 查找子串substr第一次出现的位置,如果查找的子串不存在时,则返回-1

s='hello,hello'
print(s.find('lo'))	#输出3

4.字符串大小写转换方法

upper()把字符串中所有字符都转成大写字母

s='hello'
a=s.upper()
print(a)	#输出HELLO(a和s的地址不同,即产生一个新的字符串对象)

lower()把字符串中所有字符都转换成小写字母

s='HeLLo'
a=s.lower()
print(a)	#输出hello

swapcase()把字符串中所有大写字母转换成小写字母,把所有小写字母转换成大写字母

s='HeLlo'
a=s.swapcase()
print(a)	#输出hElLO

capitalize()把第一个字符转换为大写,把其余字符转换为小写

s='hellO,pYthon'
a=s.capitalize()
print(a)	#输出Hello,python

title()把每个单词的第一个字符转换成大写,把每个单词剩余字符转换为小写

s='HeLLO,pyThON'
a=s.title()
print(a)	#输出Hello,Python

5.字符串对齐

  • center()居中对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串

  • ljust()左对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串

  • rjust()右对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串

  • zfill()右对齐,左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,如果指定的宽度小于等于字符串的长度,返回字符串本身

6.字符串劈分

在这里插入图片描述

'''split'''
s='hello world python'
lst=s.split()	#默认劈分符为空格
print(lst)	#输出['hello','world','python']
s1='hello|world|python'
print(s1.split(sep='|'))	#通过参数sep指定劈分字符串,输出['hello','world','python']
print(s1.split(sep='|',maxsplit=1))	#通过参数maxsplit指定劈分字符串时最大劈分次数,输出						    			['hello','world|python']
'''rsplit'''
lst1=s.rsplit()
print(lst1)	#输出['hello','world','python']
print(s2.rsplit(sep='|'))	#输出['hello','world','python']
print(s2.rsplit(sep='|',maxsplit=1))	#输出['hello|world', 'python']

7.判断字符串操作的方法

isidentifier()判断指定的字符串是不是合法的标识符

s='hello,python'
print(s.isidentifier())	#False
print('hello'.isidentifier())	#True
print('张三_'.isidentifier())	#True

isspace()判断指定的字符串是否全部由空白字符组成(回车、换行、水平制表符)

print('\t'.isspace)	#True
  • isalpha()判断指定的字符串是否全部由字母组成

  • isdecimal()判断指定字符串是否全部由十进制的数字组成

  • isnumeric()判断指定的字符串是否全部由数字组成

  • isalnum()判断指定字符串是否全部由字母和数字组成

8.字符串的替换和合并

在这里插入图片描述

'''replace()'''
s='hello,python'
print(s.replace('python','java'))	#用java替换python,输出hello,java
s1='hello,python,python,python'
print(s1.replace('python','java',2))	#输出hello,java,java,python
'''join()'''
lst=['hello','java','python']
print('|'.join(lst))	#输出hello|java|python
print(''.join(lst))	#输出hellojavapython
print('*'.join('python'))	#输出p*y*t*h*o*n

9.字符串的比较操作

运算符:>,>=,<,<=,==,!=

比较规则 : 首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,依次比较下去,直到两个字符串中的字符不相等时,其比较结果就是两个 字符串的比较结果,两个字符串中的所有后续字符将不再被比较

比较原理 : 两上字符进行比较时,比较的是其ordinal value(原始值),调用内置函数ord可以得到指定字符的ordinal value。与内置函数ord对应的是内置函数chr, 调用内置函数chr时指定ordinal value可以得到其对应的字符

print('apple'>'app')	#True
print('apple'>'banana')	#False

10.字符串的切片操作

字符串是不可变类型,切片将产生新的对象

s='hello,world'	#[start:end:step]
s1=s[0:5]	#第一个数字不写默认从零开始,第二个数字不写默认到最后结束
print(s1)	#s1为hello
s0='hello,python'
s2=s0[0:7:2]	#s2为hlop
s3=s0[::-1]	#s3为nohtyp,olleh
s4=s0[-6::1]	#s4为python

11.格式化字符串

在这里插入图片描述

'''%s占位符'''
name='张三'
age=30
print('我叫%s,今年%d岁' % (name,age))
'''{}占位符'''
print('我的名字叫{0},我今年{1}岁,我真的叫{0}'.format(name,age))
'''f-string格式化'''
print(f'我叫{name},今年{age}岁')
'''其他'''
print('%10d',99)	#10表示的是宽度
print('%.3f'%3.141592)	#四舍五入保留三位小数
print('%10.3f'%3.1415926)	#10为宽度,3为保留的小数点后位数
print('{0:.3}'.format(3.1415278))	#0为索引,3为保留位数(一共的位数),输出3.14
print('{0:.3f}'.format(3.1415278))	#.3f为保留三位小数
print('{0:10.3f}'.format(3.1415278))	#.3f为保留三位小数,10为宽度

12.字符串的编码与解码

编码

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

解码

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

函数

1.函数的定义与调用

'''创建'''
def	函数名([输入参数]):
    函数体
   [return xxx]
#例如:
def calc(a,b):
    c=a+b
    return c
#调用
result=calc(10,20)
print(result)

在这里插入图片描述

2.参数的传递

位置传参

def cala(a, b):	#a和b称为形式参数,简称形参,形参的位置是在函数定义处
    c = a + b
    return c
result=cala(10,20)	#10和20为实际参数的值,简称实参,实参的位置是函数调用处
print(result)

关键字传参

def cala(a, b):	#a和b称为形式参数,简称形参,形参的位置是在函数定义处
    c = a + b
    return c
result=cala(b=10,a=20)	#10和20为实际参数的值,简称实参,实参的位置是函数调用处
print(result)

3.函数的返回值

函数返回多个值时,结果为元组

def fun(num):
    odd=[]	#存奇数
    even=[]	#存偶数
    for i in num:
        if i%2:
            odd.append(i)
        else:
            even.append(i)
    return odd,even
lst=[10,11,12,13,14,15]
print(fun(lst))	#输出([11, 13, 15], [10, 12, 14])

函数在定义时,是否需要返回值,视情况而定

4.函数参数的定义

函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参

def fun(a,b=10):
	print(a,b)
fun(100)	#只传一个参数,b采用默认值,输出100 10
fun(20,30)	#f30将默认值10替换,输出20 30

个数可变的位置参数:定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数;使用*定义个数可变的位置形参;结果为一个元组

def fun(*args):
    print(args)
fun(10)	#输出(10,)
fun(10,20,45,60)	#输出(10, 20, 45, 60)

个数可变的关键字形参:定义函数时,无法事先确定传递关键字的实参的个数时,使用可变的关键字形参;使用**定义个数可变的关键字形参;结果为一个字典

def fun(**args):
    print(args)
fun(a=10)	#输出{'a': 10}
fun(a=10,b=20,c=50)	#输出{'a': 10, 'b': 20, 'c': 50}

位置可变参数和关键字可变参数只能是一个

def fun(*args,*args1)	#会报错,因为个数可变参数只能有一个
	pass
def fun1(**args2,**args3)	#会报错,因为关键字可变参数只能有一个
	pass
def fun2(*args4,**args5)	#不会报错
	pass

5.变量的作用域

程序代码能访问该变量的区域

局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会就成全局变量

def fun(a,b):
    c=a+b	#c称为局部变量,因为c实在函数体捏进行定义的变量,a,b为函数的形参,作用范围也是函				#数内部,相当于局部变量
    print(c)
'''global声明为全局变量'''
def fun1():
    global age	#函数内部定义的变量,局部变量,局部变量使用global声明,这个变量就成了全局变量
    age=20
    print(age)

全局变量:函数体外定义的变量,可作用于函数内外

name='小朱'	#name的作用范围为函数内部和外部都可以使用,称为全局变量
print(name)
def fun():
    print(name)

6.递归函数

如果在一个函数的函数体内调用了该函数本身,这个函数就称为递归函数

递归的组成部分有递归调用与递归终止条件

递归的调用过程:

  • 每递归调用一次函数,都会在栈内存分配一个栈帧

  • 每执行完一次函数,都会释放相应的空间

递归的优缺点:

  • 缺点:占用内存多,效率低下

  • 优点:思路和代码简单

'''递归计算阶乘'''
def fun(n):
    if n==1:
        return 1
    else:
        return n*fun(n-1)
print(fun(6))

BUG

1.Bug的常见类型

粗心导致的语法错误

 
'''1'''
age=input('请输入你的年龄:')	#input输入的都是str类型,需要强制类型转换
if age>=18
	print('成年人,做事需要负法律责任')
'''2'''
while i<10:	#没有给i赋值
    print(i)	#用了中文括号

漏了末尾的冒号,如if循环语句,else子句等

缩进错误,该缩进的不缩进,不该缩进的瞎缩进

把英文符号写成中文符号,比如引号、冒号、括号

字符串拼接的时候,把字符串和数字拼在一起

没有定义变量,比如while的循环条件的变量

“==”比较运算符和“=”赋值运算符的混用

2.被动掉坑

'''若除数为0,则程序将会报错:ZeroDivisionError'''
a=int(input('请输入一个整数'))
b=int(input('请输入一个整数'))
result=a/b
print('结果为:',result)
'''利用try-expect结构'''
try:
    a=int(input('请输入一个整数'))
    b=int(input('请输入一个整数'))
    result=a/b
    print('结果为:',result)
expect ZeroDivisionError:	#如果出现ZeroDivisionError错误将会执行以下语句
    print('除数不能为0')

可以采用try-expect-expect-expect…结构,也可以采用try-expect-expect…else结构

try:
    a=int(input('请输入一个整数'))
    b=int(input('请输入一个整数'))
    result=a/b
except ZeroDivisionError:	#如果出现ZeroDivisionError错误将会执行以下语句
    print('除数不能为0')
except ValueError:
    print('出错了')
else:
    print('结果为:',result)

try-except-except…else-finally结构:

和上面的差不多,唯一不同的就是不论是否报错,finally块都会执行

python中常见的异常类型

序号异常类型描述
1ZeroDivisionError取(或取模)零(所有数据类型)
2IndexError序列中没有此索引(index)
3KeyError映射中没有这个键
4NameError未声明/初始化对象(没有属性)
5SyntaErrorpython语法错误
6ValueError传入无效的参数

1.traceback模块的使用

import traceback
try:
    print('-----------')
    print(1/0)
except:
    traceback.print_exc()

在这里插入图片描述
输出的横线有时候在前,有时候在中,有时候在后。

类与对象

1.类与对象

类:类是多个类似事物组成的群体的统称。能够帮助我们快速理解和判断事物的性质

对象:100、99、520都是int类之下包含的类似的不同个例,这个个例专业术语称为实例或对象

2.类的创建

创建类的语法:

class Student:	
'''Student为类的名称,简称类名,由一个单词或多个单词组成,每个单词首字母大写,其余小写(不大写也可,不报错)'''
    pass

类的组成:类属性、实例方法、静态方法、类方法

class Student:
    native_pace='吉林'    #直接写在类里的变量,称为类属性
    def eat(self):  #实例方法,在类里面定义的称为方法,在类之外定义的叫函数
        print('学生在吃饭......')
    '''静态方法'''
    @staticmethod
    def method():   #静态方法不允许写self
        print('我使用了staticmethod进行修饰,所以我是静态方法')
    '''类方法'''
    @classmethod
    def cm(cls):
        print('我是类方法,因为我使用了classmethod进行修饰')
    def __init__(self,name,age):
        self.name=name  #self称为实例属性,进行了一个叫赋值的操作,将局部变量的name的值赋给实例属性,self.后不一定非叫name,叫什么都可以,name只是一种习惯
        self.age=age

3.对象的创建

对象的创建又称为类的实例化

语法:实例名=类名()

#创建Student类的实例对象
stu=Student('Jack',20)
print(stu.name)	#实例属性
print(stu.age)	#实例属性
stu.info()	#实例方法

意义:有了实例,就可以调用类中的内容

class Student:
    native_pace='吉林'    #直接写在类里的变量,称为类属性
    def eat(self):  #实例方法,在类里面定义的称为方法,在类之外定义的叫函数
        print('学生在吃饭......')
    '''静态方法'''
    @staticmethod
    def method():   #静态方法不允许写self
        print('我使用了staticmethod进行修饰,所以我是静态方法')
    '''类方法'''
    @classmethod
    def cm(cls):
        print('我是类方法,因为我使用了classmethod进行修饰')
    def __init__(self,name,age):
        self.name=name  #self称为实例属性,进行了一个叫赋值的操作,将局部变量的name的值赋给实例属性,self.后不一定非叫name,叫什么都可以,name只是一种习惯
        self.age=age
#创建Student类的对象
stu1=Student('张三',20)
stu1.eat()	#对象名.方法名
Student.eat(stu1)	#与上一行代码功能相同,都是调用Student中的eat方法
				   #类名.方法名(类的对象)-->实际上就是方法定义处的self
print(stu1.name)
print(stu1.age)

4.类属性

类属性:类中方法外的变量称为类属性,被该类的所有对象所共享

类方法:使用@classmethod修饰的的方法,使用类名直接访问的方法

静态方法:使用@staticmethod修饰的方法,使用类名直接访问的方法

class Student:
    native_pace='吉林'    #直接写在类里的变量,称为类属性
    def eat(self):  #实例方法,在类里面定义的称为方法,在类之外定义的叫函数
        print('学生在吃饭......')
    '''静态方法'''
    @staticmethod
    def method():   #静态方法不允许写self
        print('我使用了staticmethod进行修饰,所以我是静态方法')
    '''类方法'''
    @classmethod
    def cm(cls):
        print('我是类方法,因为我使用了classmethod进行修饰')
    def __init__(self,name,age):
        self.name=name  #self称为实例属性,进行了一个叫赋值的操作,将局部变量的name的值赋给实例属性,self.后不一定非叫name,叫什么都可以,name只是一种习惯
        self.age=age
#类属性的使用方式
print(Student.native_pace)
stu1=Student('张三',20)
stu2=Student('李四',30)
print(stu1.native_pace) #输出吉林
print(stu2.native_pace) #输出吉林
Student.native_place='天津'
print(stu1.native_pace) #输出天津
print(stu2.native_pace) #输出天津
#类方法的使用方式
Student.cm()
#静态方法的使用方式
Student.method()

5.动态绑定属性和方法

python是动态语言,在创建对象之后可以动态的绑定属性和方法

class Student:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def eat(self):
        print(self.name+'在吃饭')
stu1=Student('张三',20)
stu2=Student('李四',30)
#为stu2动态绑定性别属性
stu2.gender='女'
print(stu1.name,stu1.age)
print(stu2.name,stu2.age,stu2.gender)
'''为stu1绑定show函数'''
def show():
    print('定义在类之外的,称为函数')
stu1.show=show  #为stu1绑定了show函数
stu1.show()
stu2.show() #这行代码会报错,因为没有为stu2绑定show函数
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值