上一篇:参考博客
参考
try: 可能会出异常的代码 except Exception1: 异常处理
try: a = int(input("第一个整数")) b = int(input("第二个整数")) result = a/b print("结果为", result) except ZeroDivisionError: print("除数不允许为0") print("程序结束")
多个exception结构:
捕获一场的顺序按照先子类后父类的顺序,为了避免遗漏可能出现的异常,可以在最后增加BaseException
try: 可能会出异常的代码 except Exception1: 异常处理 except Exception2: 异常处理 except BaseException: 异常处理
try: a = int(input("第一个整数")) b = int(input("第二个整数")) result = a/b print("结果为", result) except ZeroDivisionError: print("除数不允许为0") except ValueError: print("只能输出数字串") print("程序结束")
如果try块中没有抛出异常,则执行else块,如果try中抛出异常,则执行except块
try: a = int(input("第一个整数")) b = int(input("第二个整数")) result = a/b print("结果为", result) except BaseException as e: print("出错了", e) else: print("计算结果为", result)
finall无论是否发生异常都会被执行,能常用来释放try块中申请的资源。
try: a = int(input("第一个整数")) b = int(input("第二个整数")) result = a/b print("结果为", result) except BaseException as e: print("出错了", e) else: print("计算结果为", result) finally: print("谢谢您的使用")
参考
面向对象:只找这件事情的参与者,不在乎过程。
面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
class Student(object): pass
class Student: native_pace = '黑龙江' # 直接写在类里的变量,称为类属性 def __init__(self, name, age): # self.name称为实体属性,进行了一个赋值操作,降局部变量的name赋值给实体属性 self.name = name self.age = age def eat(self): # 实例方法 print("学生在吃饭") @staticmethod def method(): # 静态方法中是不允许使用self的 print("我使用了staticmethod进行修饰,所以我是静态方法") @classmethod def cm(cls): print("我是类方法,因为我使用了classmethod进行修饰") # 在类之外定义的称为函数,在类之内定义的称为方法 def drink(): # 函数 print("喝水")
# 创建Student类的对象 stu1 = Student("张三", 20) print(id(stu1)) print(type(stu1)) print(stu1)
4563833760
<class ‘main.Student’>
<main.Student object at 0x1100693a0>
最下面这个十六进制转为十进制其实就是上面那个数字
# 创建Student类的对象 stu1 = Student("张三", 20) print(id(stu1)) print(type(stu1)) print(stu1) print(id(Student)) print(type(Student)) print(Student)
4511086720
<class ‘main.Student’>
<main.Student object at 0x10ce1b880>
140274309310848
<class ‘type’>
<class ‘main.Student’>
实例对象中会有一个类指针指向它所创建的类对象
# 创建Student类的对象 stu1 = Student("张三", 20) stu1.eat() # 类的实例对象可以调用实例方法和属性 对象名.方法名() print(stu1.name) print("-------") Student.eat(stu1) # 与stu1.eat()功能相同,都是调用Student中的eat方法 # eat方法要求传入self,也就是对象本身,所以必须传入参数 # 类名.方法名(类的对象) ---- >实际上就是方法定义处的self
python中一切皆对象,就算是类,其实也是对象的一种,我们称为类对象。
实例方法、类方法和静态方法
类属性、类方法和静态方法
(1)类属性:
# 类属性的使用 print(Student.native_pace) stu1 = Student("张三", 20) stu2 = Student("李四", 30) print(stu1.native_pace) print(stu2.native_pace) Student.native_pace = '天津' print(Student.native_pace) print(stu1.native_pace) print(stu2.native_pace)
黑龙江
黑龙江
黑龙江
天津
天津
天津
(2)类方法
stu1 = Student("张三", 20) stu2 = Student("李四", 30) Student.cm() stu1.cm() stu2.cm()
我是类方法,因为我使用了classmethod进行修饰
我是类方法,因为我使用了classmethod进行修饰
我是类方法,因为我使用了classmethod进行修饰
(3) 静态方法:
stu1 = Student("张三", 20) Student.method() stu1.method()
我使用了staticmethod进行修饰,所以我是静态方法
我使用了staticmethod进行修饰,所以我是静态方法
(4)实例方法:Python 的实例方法用得最多,也最常见。
Python是动态语言,在创建对象之后,可以动态地绑定属性和方法。
(1)动态绑定属性
class Student: native_pace = '黑龙江' # 直接写在类里的变量,称为类属性 def __init__(self, name, age): # self.name称为实体属性,进行了一个赋值操作,降局部变量的name赋值给实体属性 self.name = name self.age = age def eat(self): # 实例方法 print(self.name + "在吃饭") stu1 = Student("张三", 20) stu2 = Student("李四", 30) print(id(stu1)) print(id(stu2)) print("----为stu2动态绑定性别属性-----") stu2.gender = '女' print(stu1.name, stu1.age) print(stu1.name, stu1.age,stu2.gender) # 如果你要输出stu1的性别,程序会报错的。因为我们只为stu2进行了动态绑定,并没有为stu1动态绑定
4565257088
4565850240
----为stu2动态绑定性别属性-----
张三 20
张三 20 女
(2)动态绑定方法
class Student: native_pace = '黑龙江' # 直接写在类里的变量,称为类属性 def __init__(self, name, age): # self.name称为实体属性,进行了一个赋值操作,降局部变量的name赋值给实体属性 self.name = name self.age = age def eat(self): # 实例方法 print(self.name + "在吃饭") stu1 = Student("张三", 20) stu2 = Student("李四", 30) def show(): print("定义在类之外的,称为函数") # 动态绑定函数 stu1.show= show stu1.show() stu2.show() # 报错,因为stu2没有动态绑定show方法
定义在类之外的,称为函数
参考:封装、继承、多态
(1)封装
class Student: def __init__(self, name, age): self.name = name self.__age = age # age不希望在外部使用,所以加了__变为私有变量 def show(self): print(self.name, self.__age) stu1 = Student("张三", 20) stu1.show() # 在类的外部使用name和age print(stu1.name) # 不报错 # print(stu1.__age) # 报错,因为实例对象不能在类的外部使用私有变量 print(stu1._Student__age) # 在类的外部可以通过,_Student__age进行访问 # python的封装性靠的是程序员的自觉性,看到私有变量就别访问了,你非得访问是可以访问的,但是不建议这种访问方式
5个模块:
(1):直接调用父类属性方法
(2):强制调用父类私有属性方法
(3):重写父类属性方法
(4):调用父类的__init__方法
(5):继承父类初始化过程中的参数
子类继承父类的所有属性和方法,子类的实例化对象可以使用父类的所有属性和方法,但是注意私有属性和方法。
如果父类的方法是私有方法,如 def __action(self)
这样的话再去调用就提示没有这个方法,其实编译器是把这个方法的名字改成了_父类名__方法名()
_Father__action()
,如果强制调用,可以这样:super()._Father__action()
super()
__init__
方法__init__
方法,说明子类已经将父类的初始化方法重写了,那么子类不可以直接调用父类的属性。__init__
中调用一下父类的 __init__
方法,这样就可以调用了class Father(): def __init__(self): self.a='aaa' class Son(Father): def __init__(self): super().__init__() #也可以用 Father.__init__(self) 这里面的self一定要加上 son=Son() print(son.a)
class Father(): def __init__(self,a,b): self.a = a self.b = b def dev(self): return self.a - self.b #调用父类初始化参数a,b并增加额外参数c class Son(Father): def __init__(self,a,b,c=10): # 固定值: 例如默认c=10,也可以显示地将c赋值 Father.__init__(self,a,b) # 或者写下面这句: # super().__init__(self,a,b) self.c = c def add(self): return self.a+self.b def compare(self): if self.c > (self.a+self.b): return True else: return False son=Son(1,2) # 由于c在初始化过程中默认为10,所以c可以不用显示表达出来 print(son.dev()) # 调用父类dev函数 print(son.add()) # 子类自身add函数 print(son.compare()) # 子类自身compare函数
结果:
-1
3
True
dir()
可以查看指定对象所有属性和方法。__str__()
方法,用于返回一个对于“对象的描述”,对应于内置函数str()经常用于print()方法,帮我们查看对象信息,所以我们经常会对__str__()
进行重写。class Student: pass stu = Student() print(dir(stu))
[‘class’, ‘delattr’, ‘dict’, ‘dir’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘gt’, ‘hash’, ‘init’, ‘init_subclass’, ‘le’, ‘lt’, ‘module’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘setattr’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘weakref’]
class Student: pass stu = Student() print(stu) # <__main__.Student object at 0x100b6ab80>
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(stu) # 我的名字是张三,今年20岁 # 默认会调用__str__方法
一旦对__str__
进行重写,则不会输出内存地址,而是输出重写的内容。
参考
(1)特殊属性
class A: pass class B : pass class C(A,B): def __init__(self,name): self.name = name x = C("Jack") print(x.__dict__) # {'name': 'Jack'} print(C.__dict__) # {'__module__': '__main__', '__init__': <function C.__init__ at 0x10e185430>, '__doc__': None} print(x.__class__) # <class '__main__.C'> 输出对象所属的类 print(C.__bases__) # (<class '__main__.A'>, <class '__main__.B'>)# 输出父类的元组 print(C.__base__) #<class '__main__.A'> 输出最近父类 print(C.__mro__) #查看类的继承关系,类的层次关系 (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>) print(A.__subclasses__()) #输出子类列表 [<class '__main__.C'>]
(2)特殊方法
参考
__add__()
函数a = 20 b = 100 c = a + b d = a.__add__(b) print(c) print(d) class Student: def __init__(self, name): self.name = name stu1 = Student("张三") stu2 = Student("李四") s = stu1 + stu2 print(s) # 报错 # TypeError: unsupported operand type(s) for +: 'Student' and 'Student' # 如果非要相加,则要重写__add__()函数
class Student:`在这里插入代码片` def __init__(self, name): self.name = name def __add__(self, other): return self.name + other.name stu1 = Student("张三") stu2 = Student("李四") s = stu1 + stu2 print(s) # 张三李四
参考:new和init区别
什么时候使用new,单例模式的时候会使用到
__init__
函数并不是真正意义上的构造函数,__init__
方法做的事情是在对象创建好之后初始化变量。真正创建实例的是__new__
方法。__new__
方法用于创建对象并返回对象,当返回对象时会自动调用__init__
方法进行初始化。__new__
方法是静态方法,而__init__
是实例方法。
直接赋值、浅拷贝和深拷贝