析构方法(del())
用于删除销毁对象,程序结束自动调用该方法。用del删除对象时也会调用该方法。
class Animal:
def __init__(self,name):
self.name = name
print('构造方法')
pass
def __del__(self):
print('析构方法')
pass
pass
cat = Animal('mimi')
对象cat被清理,内存空间被释放
继承
子类继承父类的属性和方法,即父类有的所有属性和方法子类都有
** 单继承**
class Animal:
def eat(self):
print('吃')
pass
def drink(self):
print('喝')
pass
pass
class Dog(Animal):
def wwj(self):
print('汪汪')
pass
pass
class Cat(Animal):
def mmj(self):
print('喵喵')
pass
pass
dog = Dog()
dog.eat()
cat = Cat()
cat.drink()
多继承
子类可以继承多个父类,且继承具有传递性,子类可以继承父类的父类
class Animal:
def eat(self):
print('吃')
pass
def drink(self):
print('喝')
pass
pass
class Pet:
def woshou(self):
print('握手')
pass
pass
def eat(self):
print('喂食')
pass
class Dog(Animal,Pet):
def wwj(self):
print('汪汪')
pass
pass
dog = Dog()
dog.eat() #吃 当继承的父类方法重名时,调用的优先级按照继承的先后顺序
dog.woshou()
重写
若子类中有和父类同名的方法,子类中的方法会覆盖父类的方法
class Animal:
def eat(self):
print('吃')
pass
pass
class Dog(Animal):
def wwj(self):
print('汪汪')
pass
def eat(self):
super().eat()#调用父类方法
print('小狗吃饭')
pass
dog = Dog()
dog.eat() #小狗吃饭
多态
1.继承:必须发生在父类和子类之间
2.重写:子类重写父类方法
class Animal:
def say(self):
print('我是一个动物')
pass
pass
class Duck(Animal):
def say(self):
print('我是一只鸭子')
pass
class Dog(Animal):
def say(self):
print('我是一只狗狗')
pass
class Cat(Animal):
def say(self):
print('我是一只猫猫')
pass
def commonInvoke(obj):
obj.say()
pass
list = [Duck(),Dog(),Cat()]
for i in list:
commonInvoke(i)
类属性和实例属性
类属性是类所拥有的属性,类和实例对象都可访问(相当于Java中的全局变量)
实例属性是实例对象所拥有的属性,只能通过实例对象访问(相当于Java中的局部变量)
class Student:
name = '李明' #类属性
def __init__(self,age):
self.age = age #实例属性
pass
pass
lm = Student(18)
print(lm.name) #通过对象访问类属性
print(lm.age) #通过对象访问实例属性
print(Student.name) #通过类访问类属性
print(Student.age) #错误
类方法和静态方法
类对象所拥有的方法,需要用装饰器@classmethod来标识,第一个参数必须是类对象一般用cls,类方法可以被类和实例对象调用。
静态方法需要@staticmethod来表示,静态方法没有必要参数。
使用静态方法的原因:
静态方法中一般用来存放逻辑性代码,不涉及类中的方法和属性。数据资源能够得到有效的充分利用
class Person:
country = '中国' #类属性
@classmethod
def get_country(cls): #类方法
return cls.country #访问类属性
pass
@classmethod
def change_country(cls,data): #通过类方法修改类属性
cls.country = data
pass
@staticmethod
def getData():
return Person.country
pass
pass
print(Person.get_country()) #通过类对象引用
p = Person()
print(p.get_country()) #通过实例对象访问
print(p.getData()) #通过实例对象访问静态方法(一般不用)
Person.change_country('美国')
print(Person.get_country())
print(Person.getData()) #通过类对象访问静态方法
私有化属性
语法:两个下划线开头,不能在类的外部被访问或直接使用
#使用私有属性的场景
#1.把特定的属性隐藏,不让类的外部直接调用
#2.保护属性,不让属性的值随意改变
#3.保护属性,不让子类继承
class Person:
def __init__(self):
self.__name = 'zs' #私有化 外部不能直接访问,但类的内部可以使用
self.age = '22'
pass
def __str__(self):
return '{}年龄是{}'.format(self.__name,self.age)
pass
class Student(Person): #子类不能调用父类私有化属性
pass
zs = Person()
print(zs)
私有化方法
语法:在方法名前面加两个下划线
class Animal:
def __eat(self): #私有化,子类不能调用
print('chi')
def run(self):
print('pao')
pass
class Bird(Animal):
pass
b = Bird()
Property属性
第一种方式
class Person:
def __init__(self):
self.__age = 18
def get_age(self): #访问私有属性
return self.__age
def set_age(self,age): #修改私有属性
if age < 0:
print('error')
else:
self.__age = age
age = property(get_age,set_age) #通过该函数可以在外部直接访问私有属性
p = Person()
print(p.age)
第二种方式 装饰器
class Person:
def __init__(self):
self.__age = 18
@property #用装饰器修饰 添加属性标志 提供getter方法
def age(self):
return self.__age
@age.setter #提供setter方法
def age(self,parms):
if parms < 0:
print('error')
else:
self.__age = parms
pass
p = Person()
print(p.age)
** __new__方法**
创建并返回一个实例对象。
(1)__new__是在一个对象实例化后调用的第一个方法
(2)__new__至少必须要有一个参数cls,代表要实例化的类,此参数在实例化时由python解释器自动提供,其他的参数是用来直接传递给__init__方法
(3)在__new__中不能调用自己__new__方法,即return cls.new(cls)
异常处理
语法格式:
try:
可能出现错误的代码块
except:
出错后执行的代码块
else:
没有出错的代码块
finally:
一定要执行的代码块
try:
print(b)
pass
except NameError as msg:
print(msg)
pass
动态添加属性
import types
class Student:
def __init__(self,name,age):
self.name = name
self.age = age
pass
def __str__(self):
return '{}今年{}岁'.format(self.name,self.age)
pass
def dymicMethod(self):
print('{}体重{},在{}上大学'.format(self.name,self.weigth,Student.school))
pass
zs = Student('zs',18)
zs.weigth = 80 #动态添加实例属性
Student.school='abc' #动态添加类属性
zs.printInfo = types.MethodType(dymicMethod,zs) #动态的绑定方法
zs.printInfo()
** __slots__变量 **
用该变量限制给类添加属性,只有在__slots变量中的属性才能被添加。该属性子类不会被继承,只在当前类中有效。