python可以查询一个类有多少个引用,不过使用该方法,需要一个模块
#查看引用 import sys class Student(object): pass student = Student(); print(sys.getrefcount(student))
如果删除刚刚创建好的引用,就会报错
del student print(sys.getrefcount(student))
错误信息 : NameError: name 'student' is not defined
继承:
当我们定义一个类的时候,可以从某个类继承,继承的类,就被称之为派生类或者叫做子类,
而被继承的类称为基类、父类或者超类
子类继承父类,子类可以使用父类的属性和方法,简化代码.
当生成子类对象时,先初始化父类对象,所以如果父类有__init__()方法,并且有属性时,要通过子类的构造赋值。
class Person(object): #父类 def __init__(self,name,age): self.name = name self.age = age def run(self): print("父类中的方法run") class Student(Person): #子类,继承person def __init__(self,name,age,sex): self.name = name self.age = age self.sex=sex def __str__(self): return "我的名字是:{0}年龄为:{1}我的性别是:{2}".format(self.name,self.age,self.sex) student = Student("张三",19,"男") print(student) #子类没有run方法,但子类可以使用父类的run方法 student.run()
打印结果:
我的名字是:张三年龄为:19我的性别是:男
父类中的方法run
多继承:
python同样支持多继承,一个子类可以有多个父类。
子类传递参数给父类:
在子类中,调用父类的属性时,在__init__()方法中使用
父类.属性,或self.属性或父类.__init__(self,参数)或super(父类,self).__init__(参数)四种方法给父类传参调用父类方法时:super().父类方法()
需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法
三代继承:子类初始化方法需要祖父、父类及自己的属性,可以调用父类的初始化方法传参,可以重写父类的方法
构造的顺序依然先构造祖父类,再构造父类,最后构造自己
方法重写:
如果子类重写的方法想调用父类的方法时,在子类方法中:父类.方法(self)或super().父类方法()
私有属性、私有方法:均不能在类外面被调用
多继承:类同时继承多个父类,class C(A,B),当有AB均有相同方法,而子类又重写时,调用子类的方法,如果子类没有方法,则调用从左到右第一个父类的方法。
类名.mro(),可以看到所有父类,即搜索顺序。
多态:
多态是指一类事务有多种形态,一个类有多个子类,从而形成了多态
class Person(object): #定义一个方法什么也不做,子类负责实现该方法 def run(self): pass class Student(Person): #重写父类方法 def run(self): print("学生再跑") class Teacher(Person): #重写父类的方法 def run(self): print("老师在跑") person = Student() person.run() person = Teacher() person.run()
学生再跑
老师在跑
结论: 通过不同的子类,得到的内容也不相同!
类属性:属于类的成员,属于对象共有的,不在方法体内定义
类方法:在方法上添加@classmethod
@classmethod
def class_method(cls):
可以通过类方法调用类属性,也可以通过对象调用类属性
静态方法:方法前加@staticmethod,静态方法没有参数,静态方法既和类没关系,也和对象没关系,也可以通过类和对象调用
工厂类:有一些子类,在一个类中生成很多对象,简单工厂模式
class Cat(object): # 类属性 num = 0 row=100 @classmethod def leiMethod(self,name): print("这是类方法",name) @staticmethod def smethod(): #静态方法是没有参数的 print("这是静态方法") def __init__(self): #实例属性 self.age = 1 #如类属性的名字和实例属性的名字相同,那么通过,对象获取num的时候 #那么会获取实例属性的值 self.num = 100 def run(self): print("-----猫在跑---") mao = Cat() #使用对象去访问 print(mao.num) #100 #常用的方式 使用类去访问类属性 print(Cat.num) #0 Cat.num+=1 print(Cat.num) # 1 print(mao.row) # 100 #是用对象修改类属性,相当于创建了一个实例属性,并没有修改类属性 mao.row+=400 print(mao.row) #500 print(Cat.row) #100 #调用类方法 Cat.leiMethod("张三") #调用静态方法 Cat.smethod()
函数: __init(self)__ : 对象创建完之后会调用默认调用该函数,主要用于完成对象的初始化设置 __new__(cls)的使用: def __new__(cls, *args, **kwargs): print("---------new-------") return object.__new__(cls) 对象创建的过程中会调用该函数,比__init__()函数,要先执行,不过该函数 一定要有返回值,cls指的是,当前这个类
当有属性时,需要在__new__()中也添加属性
class Test(object): def __init__(self,name): self.name = name #如果__init__有参数的话,那么__new__()函数要这么写,不然会报异常 def __new__(cls, *args, **kwargs): print("这是 new") return object.__new__(cls) def __str__(self): return "名字为:{0}".format(self.name) test = Test("张三") print(test)
单例模式
一个类不论实例化多少次,用函数id(变量),得到的地址值是不变的,是一样的
#单例 class Singleton(object): __instance = None def __new__(cls, *args, **kwargs): if cls.__instance == None: cls.__instance = object.__new__(cls); return cls.__instance a = Singleton() print(id(a)) b = Singleton() print(id(a))对象列表进行排序:按照什么进行排序,重写__lt__方法:
class Person:
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):
return "姓名:%s,年龄:%d"%(self.name,self.age)
def __lt__(self, other):
if self.name==other.name:
return self.age<other.age
else:
return self.name.encode('gbk')>other.name.encode('gbk')
支持中文排序
peple=[Person("abc",20),Person("aabc",22),Person("abc",21),Person("aabc",23)]
peple.sort()
for m in peple:
print(m)
还可以使用切片,进行排序
lists2 = [Car("宝马2", 2002), Car("奥迪2", 1002), Car("野马2", 3002), Car("大奔2", 6002)] lists2.sort(key=lambda x:x.price,reverse=True) for i in lists2: print(i,end=" ")
异常: 即有一些代码语法正确,但运行时会发生错误,运行期检测的错误被称为异常。 解决异常: 1.捕获多个异常 try:...except:.. try: print(1/0) except 异常的名字: #还可以显示异常的基本信息 except 异常的类型 as 随便一个名字: # print(随便一个名字)就可以输出异常的基本信息 print("提示出现的异常,并给出对应解决方法") except 异常的名字: print("提示出现的异常,并给出对应解决方法") ......可以有多个 2.#捕获全部异常 try: print(1/0) except : #加个冒号,如果想捕获异常信息就需要这样写 except Exception as ex: print("出现异常") 3.else,代表没有异常的时候会执行else try: #如果产生了一个异常,但是except没有捕获,那么就会按照这个异常默认的处理方式进行处理 a=100 print(a) except Exception as ex: print("出现异常",ex) else: #在try中代码都没有产生异常的时候,才会执行的代码 print("-----else--------") 4.try:...finally:... 在程序中,如果一个代码必须要执行,即无论异常是否产生都要执行,那么此时就需要使用finally。 try: print(a) except Exception as ex: print("出现异常",ex) else: print("-----else--------") finally: #最后执行 print("这是finally") 5.自定义异常 #自定义异常 class Test(Exception): def __init__(self,length,atleast): self.length = length self.atleast=atleast try: #手动抛出异常,确保抛出异常的类要继承Exception #手动抛出异常的关键字 raise Test(1,2) except Test as ex: print("testtetste") print(ex)