try...except 结构

try...except 结构,用于防止被动掉坑。例如,输入b的值时,手抖了一下,除数不能为0,程序就会报错。有了这个异常处理机制,当出现了类似的情况时,就会执行对应情况的代码,防止报错。

try:
    a=int(input('请输入第一个数'))
    b=int(input('请输入第二个数'))
    c=a/b
    print('结果为',c)
except ZeroDivisionError:
    print('除数不能为0')
except ValueError:
    print('请输入正确的数字')
print('程序结束')

try.....except...else结构 二选一执行的

try:
    a=int(input('请输入第一个数'))
    b=int(input('请输入第二个数'))
    c=a/b
except BaseException as e:
    print('出错了',e)        #这个e会告诉你出了什么错
else:
    print('计算结果为:',c)

try..except...else...finally结构

finally无论发生什么都会执行,通常用来释放try中申请的资源

try:
    a=int(input('请输入第一个数'))
    b=int(input('请输入第二个数'))
    c=a/b
except BaseException as e:
    print('出错了',e)        #这个e会告诉你出了什么错
else:
    print('计算结果为:',c)
finally:
    print('thanks for using')

常见的异常类型

ZeroDivisionError 除数为0
IndexError 序列中没有这个索引
KeyError 映射中没有这个键
NameError 未声明的对象
SyntaxError 语法错误
ValueError 传入无效参数

面向过程&面向对象

图片说明
比方说,我想吃番茄炒鸡蛋。我用面向过程的方法:第一步,菜市场买鸡蛋和番茄;第二步,洗干净;第三步,锅热倒油,下入鸡蛋;第四步,鸡蛋添起来,放入西红柿;。。。。。。
如果使用面向对象:打开美团APP点一个。然后厨师会帮你做,你不需要去执行上述步骤。

类:

类是多个类似事物组成的群体的统称。能够快速整理和理解和判断事物的性质。
类(Class)是面向对象程序设计(OOP,Object-Oriented Programming)实现信息封装的基础。类是一种用户定义的引用数据类型,也称类类型。每个类包含数据说明和一组操作数据或传递消息的函数。类的实例称为对象。
定义一个类,Student 就是类名。注意规范:首字母大写。
在类之内定义的叫做方法!在类之外定义的叫做函数!直接写在类里的变量,称为类属性
def _ init _()为初始化方法

class Student:             
    native_place='武汉'   #直接写在类里的变量,称为类属性。
    def __init__(self,name,age):
        self.name=name    #  self.name实例属性,进行了一个赋值的操作,将局部变量的name的值赋值给实体属性
        self.age=age

    #2实例方法
    def eat(self):                    #默认传入自身的对象
        print(***生在吃饭...')

    #3静态方法使用@staticmethod修饰
    @staticmethod
    def method():
        print('我是用了staticmethod进行修饰,所以我是静态方法')

    #4类方法使用@classmethod修饰
    @classmethod
    def cm(cls):
        print('我是类方法,使用classmethod修饰')

def drink():
    print('喝水')

创建一个Student类的实例对象。再打印它的类型和地址。

stu1=Student('张三',20)
print('stu1t',id(stu1))       #2252700856528  十六进制后0x0000020C7F6F30D0
print('stu1',type(stu1))       #这些是 实例对象 的内存地址
print('stu1',stu1)         #<__main__.Student object at 0x0000020C7F6F30D0>

打印类对象的类型和地址。

print('Student',id(Student))
print('Student',type(Student))         #这个是类对象的地址,类对象里面有一个类指针指向实例对象
print('Student',Student)

在实例对象中有一个类指针指向创造它的类对象,当类对象创建完成之后,就可以使用这个类的实例属性,以及这个类的相关方法。
图片说明

类对象的使用方法:

方法一:实例对象名.方法名的方式调用类对象中的方法
方法二:*类名.方法名(对象名) *的方式调用类对象中的方法

stu1.eat()                
Student.eat(stu1)         #  类名.方法名(对象名)

print(stu1.age)
print(stu1.name)  

类属性的使用

创建两个实例对象,stu1、stu2。使用:类对象.类属性的方式调用。例如:print(Student.native_place)

stu1=Student('张三',20)
stu2=Student('李四',30)
print(stu1.native_place)
print(stu2.native_place)
#当改变了类属性之后:
Student.native_place='广州'

print(stu1.native_place)        #两个都是修改后的结果
print(stu2.native_place)       #两个结果一样

类方法的调用:
当方法中 需要使用类对象 (如访问私有类属性等)时,定义类方法
类方法一般和类属性配合使用

Student.cm()

静态方法的调用:
当方法中 既不需要使用实例对象(如实例对象,实例属性),也不需要使用类对象 (如类属性、类方法、创建实例等)时,定义静态方法
取消不需要的参数传递,有利于 减少不必要的内存占用和性能消耗

Student.method()

动态绑定属性和方法

1.绑定动态属性。
先创建一个类对象,其中包含初始化方法_ init _()和实例方法eat(),再创建两个实例对象stu1、stu2。

class Student:
    def __init__(self,name,age):
        self.name=name#将局部变量的值赋值给实例变量
        self.age=age
    def eat(self):
        print(self.name+'在吃饭')

stu1=Student('张三',20)
stu2=Student('李四',22)

为stu2动态绑定属性gender,再调用动态属性。对于没有绑定动态属性的stu1,是不能调用动态属性的!
具体的内存图如图所示:

stu2.gender='女'
print(stu1.name,stu1.age)
print(stu2.name,stu2.age,stu2.gender)

图片说明

2.动态绑定方法/函数

def show():
    print('定义在类之外,称为函数')
stu1.show=show #动态绑定方法

stu1.show() #调用动态绑定的方法

面向对象的三大特征

1.封装:提高程序的安全性
将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样,无需关心方法内部的具体细节,从而隔离了复杂度。(参考类对象的两种使用方法)
在Python中没有专门的修饰符用于属性私有,如果该属性不希望在类对象外部被访问,前面使用两个“_”。

class Student:
    def __init__(self,name,age):
        self.name=name
        self.__age=age        #年龄不希望在类的外部被使用,所以用了两个下划线
    def show(self):
        print(self.name,self.__age)

stu=Student('张三',20)
print(stu.name)
#print(stu.__age)       #报错了,程序不希望这样使用,不过可以通过下面的方法来实现
stu.show()
#在类的外面使用name和age

虽然被两个下划线修饰的age不能这样访问,但还是有其他的办法访问。要凭程序员的自觉性,看到两个下划线最好不要访问。所谓的“防君子,不妨小人”

print(dir(stu))
print(stu._Student__age)     #20  还是可以访问,但是要凭自觉,最好不要访问

2.继承:提高代码的复用性
图片说明
object类是所有类的父类,因此所有类都有object类和属性和方法。
内置函数dir()可以查看指定对象所有属性。

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

#定义一个子类
class Student(Person):          #Student继承Person类
    def __init__(self,name,age,stu_no):
        super().__init__(name,age)    #用于调用父类的init方法,把name,age传入
        self.stu_no=stu_no

#定义另一个子类
class Teacher(Person):
    def __init__(self,name,age,teachofyears):
        super().__init__(name,age)
        self.teachofyears=teachofyears

stu=Student('张三',20,'1001')
teacher=Teacher('李四',34,10)

stu.info()
teacher.info()

2—1.方法重写
stu.info()、teacher.info()调用的是Person类里面的,无法输出学生的学号和老师的教龄。通过方法重写可以改变输出。

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

#定义一个子类
class Student(Person):
    def __init__(self,name,age,stu_no):
        super().__init__(name,age)
        self.stu_no=stu_no
    def info(self):
        super(Student, self).info()
        print(self.stu_no)           #因为只能输出name和age,不能执行stu-no,所以要重写这个方法

class Teacher(Person):
    def __init__(self,name,age,teachofyears):
        super().__init__(name,age)
        self.teachofyears=teachofyears
    def info(self):
        super(Teacher, self).info()       #对原来的方法体不满意,就可以重新写
        print('教龄',self.teachofyears)

内置函数dir()可以查看指定对象所有属性.
object有一个_str()_方法,用于返回一个对于“对象的描述”,即对象的内存地址,对应于内置函数str()经常用于print()方法,帮助我们查看对象信息。

class Student:
    pass
stu=Student()
print(dir(stu))     #可以查看对应的属性和方法,全部都是从父类object继承过来的

#对象的描述
print(stu)  #输出一个对象的内存地址 <__main__.Student object at 0x000001A064C47460>
print(id(stu))  #输出对象的内存地址,十进制的形式

当然父类的方法也可以重写,重写 _ str() _

class Student:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __str__(self):
        return '我的名字是{0},今年{1}岁了'.format(self.name,self.age)


stu=Student('张三',20)
print(dir(stu))
print(stu)          #没有输出他的类型,而是结果  :我的名字是张三,今年20岁了
print(type(stu))       #<class '__main__.Student'>

3.多态:提供程序的扩展性和可维护性
简单地说,多态就是“具有多种形态”,它指的是:即便不知道一个变量所引用的对象到低是什么类型,任然可以通过这个变量调用方法,在运行过程中根据变量所引用的对象的类型,动态决定调用哪个对象中的方法。

class Animal(object):
    def eat(self):
        print('动物会吃')

class Cat(Animal):
    def eat(self):
        print('猫吃鱼')
class Dog(Animal):
    def eat(self):
        print('狗吃屎')
class People(object):
    def eat(self):
        print('人吃五谷杂粮')

#定义一个函数
def fun(obj):
    obj.eat()

fun(Cat())
fun(Dog())       #cat和dog有自己重写的方法,所以调用自己的
fun(Animal())
print('----------------------')
fun(People())      #动态语言,在创建的时候动态地绑定属性,动态的绑定方法
#不用关心people是谁的子类,只用关心people是否由eat的行为