一、Bug
1、Bug的常见类型
(1)粗心导致的语法错误SyntaxError
(2)粗心导致错误的自查宝典
a、漏了末尾的冒号,如if语句,循环语句,else子句等
b、缩进错误,该缩进的没缩进,不该缩进的瞎缩进
c、把英文符号写成中文符号,比如说:引号,冒号,括号
d、字符串拼接的时候,把字符串和数字拼在一起
e、没有定义变量,比如说while的循环条件的变量
f、"=="比较运算符和"="赋值运算符的混用
(3)知识不熟练导致的错误
a、索引越界问题IndexError
lst = [11,22,33,44]
print(lst[4]) #索引越界
b、append()方法的使用掌握不熟练
lst = []
lst = append('A', 'B', 'C')
print(lst)
(5)思路不清导致的问题
解决方法:
a、使用print()函数
b、使用"#"暂时注释部分代码
二、Python的异常处理机制
1、被动掉坑:程序代码逻辑没有错,只是因为用户操作或者一些“例外情况”而导致的程序崩溃
解决方案:Python提供了异常处理机制,可以在异常出现时即使捕获,然后内部“消化”,让程序继续运行
try:
n1 = int(input('请输入一个整数: '))
n2 = int(input('请输入另一个整数: '))
result = n1/n2
print('结果为: ', result)
except ZeroDivisionError:
print('除数不能为0!')
2、多个except结构
捕获异常的顺序按照先子类后父类的顺序,为了避免遗漏可能出现的异常,可以在最后增加BaseException
try:
n1=int(input('请输入一个整数:'))
n2=int(input('请输入另一个整数:'))
result=n1/n2
print('结果为:',result)
except ZeroDivisionError:
print('除数不能为0!')
except ValueError:
print('不能将字符串转换为数字')
except BaseException as e:
print(e)
3、try...except...else结构
如果try块中没有抛出异常,则执行else块,如果try中抛出异常,则执行except块
try:
n1=int(input('请输入一个整数:'))
n2=int(input('请输入另一个整数:'))
result=n1/n2
except BaseException as e:
print('出错了')
print(e)
else:
print('结果为:',result)
4、try...except...else...finally结构
finally块无论是否发生异常都会被执行,能常用来释放try块中申请的资源
try:
n1=int(input('请输入一个整数:'))
n2=int(input('请输入另一个整数:'))
result=n1/n2
except BaseException as e:
print('出错了')
print(e)
else:
print('结果为:',result)
finally:
print('无论是否产生异常,总会被执行的代码')
print('程序结束')
三、Python中常见的异常类型
异常类型 | 描述 |
ZeroDivisionError | 除(或取模)零(所有数据类型) |
IndexError | 序列中没有此索引 |
KeyError | 映射中没有这个键 |
NameError | 未声明/初始化对象(没有属性) |
SyntaxError | Python语法错误 |
ValueError | 传入无效的参数 |
1、traceback
使用traceback模块打印异常信息
import traceback
try:
print('1.----------')
num=10/0
except:
traceback.print_exc()
四、编程思想
面向过程 | 面向对象 | |
区别 | 事物比较简单,可以用线性的思维去解决 | 事物比较复杂,使用简单的线性思维无法解决 |
共同点 | 面向过程和面向对象都是解决实际问题的一种思维方式 | |
二者相辅相成,并不是对立的 解决复杂问题,通过面向对象方式便于我们从宏观上把握事物之间复杂的关心,方便我们分析 整个系统:具体到微观操作,仍然使用面向过程方式来处理 |
五、类与对象
类(类别,分门别类,物以类聚,人类,鸟类,动物类,植物类......)
类是多个类似事物组成的群体的统称。能够帮助我们快速理解和判断事物的性质
1、数据类型
不同的数据类型属于不同的类
使用内置函数查看数据类型
2、对象
100、99、520都是int类之下包含的相似的不同个例,这个个例专业术语称为实例或对象
#Python中一切皆对象
六、类的创建
1、创建类的语法
class Student:
pass
2、类的组成
类属性(类中方法外的变量称为类属性,被该类的所有对象所共享)
实例方法 静态方法(使用@staticmethod修饰的主法,使用类名直接访问的方法)
类方法(使用@classmethod修饰的方法,使用类名直接访问的方法)
class Student:
native_place='吉林' #类属性
def __init__(self,name,age): #name,age为实例属性
self.name=name
self.age=age
#实例方法
def info(self):
print('我的名字叫:',self.name,'年龄是:',self.age)
#类方法
@classmethod
def cm(cls):
print('类方法')
#静态方法
@staticmethod
def sm():
print('静态方法')
#类方法
@classmethod
def cm(cls):
print('类方法')
#在类之外定义的称为函数,在类之内定义的称为方法
七、对象的创建(对象的创建又称为类的实例化)
语法: 实例名=类名()
#创建Student类的实例对象
stu=Student('Jack',20)
print(stu.name) #实例属性
print(stu.age) #实例属性
stu.info() #实例方法
有了实例,就可以调用类中的内容
八、动态绑定属性和方法
Python是动态语言,在创建对象之后,可以动态地绑定属性和方法
def show():
print('我是——函数')
stu=Student('Jack',20)
stu.gender='男' #动态绑定性别
print(stu.name, stu.age, stu.gender)
stu.show=show #动态绑定方法
stu.show()
#一个Student类可以创建N多个Student类的实例对象,每个实体对象的属性值不同
九、封装
1、面向对象的三大特征
封装:提高程序的安全性(将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离了复杂度。 在Python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个"_")
继承:提高代码的复用性
多态:提高程序的可扩展性和可维护性
2、封装的实现
def __init__(self,name,age):
self.name=name
self.__age=age #年龄不希望在类的外部被使用,所以加了两个_
def show(self):
print(self,name,self.__age)
stu=Student('张三',20)
stu.show()
#在类的外部使用name和age
print(stu.name)
#print(stu.__age)
#print(dir(stu))
print(stu._Student__age) #在类的外部可以通过 _Student__age 进行访问
十、继承
1、语法格式
class 子类类名(父类1,父类2...)
pass
如果一个类没有继承任何类,则默认继承object
Python支持多继承
定义子类时,必须在其构造函数中调用父类的构造函数
2、继承代码的实现
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)
self.score=score
#测试
stu=Student('Jack',20,'1001')
stu.info()
3、方法重写
如果子类对继承自父类的某个属性或方法不满意,可以在子类中对其(方法体)进行重新编写
子类重写后的方法中可以通过super().xxx()调用父类中被重写的方法
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)
self.score=score
def info(self):
super().info()
print('学号:{0}'.format(self.score))
#测试
stu=Student('Jack',20,'1001')
stu.info()
4、object类
object类是所有类的父类,因此所有类都有object类的属性和方法。
内置函数dir()可以查看指定对象所有属性
Object有一个__str__()方法,用于返回一个对于“对象的描述”,对应于内置函数str()经常用于print()方法,帮我们查看对象的信息,所以我们经常会对__str__()进行重写
5、多态
多态就是“具有所种形态”,它指的是:即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法。
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(obj):
obj.eat()
#开始调用函数
fun(Cat())
fun(Dog())
fun(Animal())
print('')
十一、静态语言与动态语言(Python是动态语言,Java是静态语言)
静态语言和动态语言关于多态的区别
静态语言实现多态的三个必要条件:继承,方法重写,父类引用指向子类对象
动态语言的多态崇尚“鸭子类型”当看到一只鸟走起来像鸭子、游泳起来像鸭子、收起来也像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为。
1、特殊方法和特殊属性
名称 | 描述 |
__dict__ | 获得类对象或实例对象所绑定的所有属性和方法的字典 |
__len__() | 通过重写__len__()方法,让内置函数len()的参数可以是自定义类型 |
__add__() | 通过重写__add__()方法,可使用自定义对象具有“+”功能 |
__new__() | 用于创建对象 |
__init__() | 对创建的对象进行初始化 |
class C(A,B):
def __init__(self,name,age):
self.name=name
self.age=age
#创建C类的对象
x=C('Jack',20) #x是C类型的一个实例对象
print(x.__dict__) #实例对象的属性字典
print(C.__dict__)
print(x.__class__) #<class'__main__.C'>输出了对象所属的类
print(C.__bases__) #C类的父亲类型的元素
print(C.__base__)
print(C.__mro__)