my python day6
分类:
IT文章
•
2022-05-03 15:18:45
一、类的相关知识
类:把一类事物具有相同特征和动作整合到一起
对象:基于类而创建的一个具体的实例
实例化:类生成对象的过程
关键字 class 类名:
类的文档字符串
类体
python2 中python class类名 是经典类
class类名(object) 是新式类
python3中都是新式类
类的属性:
数据属性、函数属性
都存在类的属性字典中—
实例:只有数据属性
用.的方式访问就是类属性或实例属性
1 class School:
2 '''这是一个学校类''' #类的文档字符串
3 number =100 #类的数据属性
4 def __init__(self,name,addr,type):
5 #初始化构造函数
6 self.name = name #self.name 存在实例的属性字典中,name是key 后面的name是传入的变量
7 self.addr = addr
8 self.type = type
9 def create_exam(self):
10 print("%s%s正在举行考试"%(self.type,self.name))
11 s1 = School("Ezhizen","中国","私立") #实例化一个对象
12 # print(s1)
13 print(School.number)
14 print(School.__dict__)
15 School.x = 10#添加类数据属性
16 print(School.__dict__)
17 del School.x #删除类属性
18 print(School.__dict__)
19 def zhao_sheng(self):
20 print("%s%s正在招生"%(self.type,self.name))
21 School.zhao = zhao_sheng #添加类的函数属性
22 print(School.__dict__) #类的属性字典
23 print(s1.__dict__) #字典的属性字典
24 s1.create_exam()
25 School.zhao(s1) #类调用方法时要把实例传进去
26 print(s1.name)
View Code
1 class Person:
2 number = 10
3 def __init__(self,name,age,sex):
4 self.name = name
5 self.age= age
6 self.sex = sex
7 @property #静态属性
8 def learn(self):
9 print("%s正在学python"%self.name)
10
11 def play_ball(self,ball):
12 print("%s正在打%s"%(self.name,ball))
13 @classmethod #类方法
14 def run(cls):
15 print(cls.number)
16 @staticmethod #静态方法
17 def test(a):
18 print(a)
19 p1 = Person("Ezhizen",18,"boy")
20 # p1.learn()
21 p1.learn #当函数变成静态属性时,运行函数不需要加(),就可以封装逻辑
22 Person.run() #不跟实例捆绑,只跟类捆绑
23 p1.run() #但实例也可以调用
24 Person.test(10) #静态方法,类调用,实例不能调用。只是名义上归类管理,不能使用类变量和实例变量,是类的工具包
25
26 #普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;
27 #类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;
28 #静态方法:由类调用;无默认参数;
View Code
1 class Coat:
2 def __init__(self):
3 #原价
4 self.original_price = 100
5 #折扣
6 self.discout = 0.7
7 @property
8 def price(self):
9 new_price = self.original_price*self.discout
10 return new_price
11 @price.setter
12 def price(self,value):
13 self.original_price=value
14 print("11")
15 @price.deleter
16 def price(self):
17 del self.original_price
18 print(222)
19 c1 = Coat()
20 new_price = c1.price #获得商品价格
21 print(new_price)
22 c1.price = 80 #修改商品价格
23 del c1.price #删除商品价格
View Code
1 import time
2 class Date:
3 def __init__(self,year,month,day):
4 self.year=year
5 self.month=month
6 self.day=day
7 @staticmethod
8 def now():
9 t=time.localtime()
10 return Date(t.tm_year,t.tm_mon,t.tm_mday)
11
12 class EuroDate(Date):
13 def __str__(self):
14 return 'year:%s month:%s day:%s' %(self.year,self.month,self.day)
15
16 e=EuroDate.now()
17 print(e) #我们的意图
18 import time
19 class Date:
20 def __init__(self,year,month,day):
21 self.year=year
22 self.month=month
23 self.day=day
24 # @staticmethod
25 # def now():
26 # t=time.localtime()
27 # return Date(t.tm_year,t.tm_mon,t.tm_mday)
28
29 @classmethod #改成类方法
30 def now(cls):
31 t=time.localtime()
32 return cls(t.tm_year,t.tm_mon,t.tm_mday) #哪个类来调用,即用哪个类cls来实例化
33
34 class EuroDate(Date):
35 def __str__(self):
36 return 'year:%s month:%s day:%s' %(self.year,self.month,self.day)
37
38 e=EuroDate.now()
39 print(e) #我们的意图是想触发EuroDate.__str__,此时e就是由EuroDate产生的,所以会如我们所愿
View Code
组合:一个类中存在另一个类,而且是他的组成部分
1 class School:
2 def __init__(self,name,addr):
3 self.name = name
4 self.addr = addr
5
6 class Course:
7 def __init__(self,name,price,school):
8 self.name = name
9 self.price = price
10 self.school = school
11
12 s1 = School("Ryoma School","China")
13 c1 = Course("python",1500,s1)
14 print(c1.school.name)
View Code
二、面向对象的三大特性1.封装2.多态3.继承
1.继承
继承是一种创建新类的一种方式,新建的类可以继承一个或多个父类(多继承),父类可以称为基类或超类,新建的类可以称为子类或派生类。
class A:
'''我是A类'''
pass
class B(A):
'''我是B类'''
pass
print(A.__bases__) #查看基类
print(B.__bases__)
print(A.__name__) #查看类名
print(A.__doc__) #查看文档
print(A.__module__) #__main__
print(A.__class__) #type
1 class Vehicles:
2 def __init__(self,name,power,num):
3 self.name= name
4 self.power = power
5 self.num = num
6 def run(self):
7 print("%s开动了"%self.name)
8 class Railway(Vehicles):
9 def __init__(self,name,power,num,s):
10 #子类调用父类的构造函数
11 # super().__init__(name,power,num)
12 super(Railway,self).__init__(name,power,num)
13 # Vehicles.__init__(self,name,power,num)
14 self.s = s
15 def run(self):
16 #在子类中自己定义run函数
17 print("%s%s开动了"%(self.power,self.name))
18 rail = Railway("Ezhizen","氢能",100000,15000)
19 rail.run()
View Code
当类之间有明显的不同,而且较小的类是较大类的的一个组成部分,用组合比较好
当类之间存在很大的相同,提取它们公共的部分做成基类,用继承
接口继承
定义一个类 ,提供接口函数,子类继承,去实现该方法。归一化设计。 不需要关心类是什么,只需要知道哪些功能
class Interface:
def read(self):
#定义接口函数
pass
def write(self):
#定义接口函数
#
pass
class Tex(Interface):
def read(self):
#实现接口函数
print("文本读")
def write(self):
#实现接口函数
print("文本写")
class Sata(Interface): #磁盘,具体实现read和write
def read(self):
print('硬盘数据的读取方法')
def write(self):
print('硬盘数据的读取方法')
class Process(Interface):
def read(self):
print('进程数据的读取方法')
def write(self):
print('进程数据的读取方法')
View Code
经典类中,继承顺序:深度优先. 新式类中 广度优先
1 class A:
2 def test(self):
3 print("in A")
4 class B(A):
5 # def test(self):
6 # print("in B")
7 pass
8 class C(A):
9 # def test(self):
10 # print("in C")
11 pass
12 class D(B):
13 # def test(self):
14 # print("in D")
15 pass
16 class E(C):
17 # def test(self):
18 # print("in E")
19 pass
20 class F(D,E):
21 # def test(self):
22 # print("in F")
23 pass
24 f = F()
25 f.test() #F-D-B-E-C-A #新式类中广度优先 经典类中深度优先
26 print(F.__mro__) #查看继承顺序
View Code
2.多态
不同类得到的实例化对象,调用同一种方法
1 import abc
2 class Animal(metaclass=abc.ABCMeta):
3 @abc.abstractmethod
4 def talk(self):
5 pass
6 class Dog(Animal):
7 def talk(self):
8 print("talk")
9 pass
10 class Pig(Animal):
11 def talk(self):
12 print("ddd")
13 Dog()
14 Pig()
View Code
1 import abc
2 class Animal(metaclass=abc.ABCMeta):
3 @abc.abstractmethod
4 def talk(self):
5 pass
6 class Dog(Animal):
7 def talk(self):
8 print("talk1")
9 pass
10 class Pig(Animal):
11 def talk(self):
12 print("talk2")
13 class Bird(Animal):
14 def talk(self):
15 print("talk3")
16 d1 = Dog()
17 p1 = Pig()
18 b1 = Bird()
19 d1.talk() #调用同一个方法
20 p1.talk()
21 b1.talk()
22
23 def run(obj):
24 obj.talk()
25 run(d1) #多态 不同类的实例对象调用同一个方法
26 run(p1)
27 run(b1)
View Code
3.封装
-单下划线 被隐藏起来的属性,外部不能调用,只是一种约定(私有属性)一般非公共名称用单下划线
__双下划线 私有属性,外部无法调用,只是一种约定.可以通过_类名__属性访问 如 a._P__b 如果涉及到子类,并且有些内部属性应该在子类中隐藏起来。 在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的
封装 明确区分内外,内部实现逻辑,外部无法知晓,并且为限制到内部的逻辑提供一个接口给外部使用.
私有属性在import * 时不能运行 但导入具体方法时可以运行
1 __import__("m1.t") #导入顶层m1模块
2 import importlib
3 importlib.import_module("m1.t") #导入底层t模块
1 class Room:
2 def __init__(self,name,length,width,height):
3 self.name = name
4 self.length = length
5 self.width = width
6 self.height = height
7 def show_area(self):
8 return self.length * self.width
9
10 r1 = Room("Ezhizen",12,12,12)
11 area = r1.show_area()
12 print("Ezhizen住的面积",area)
13 class Room:
14 def __init__(self,name,length,width,height):
15 self.name = name
16 self.__length = length
17 self.__width = width
18 self.height = height
19 def __show_area(self):
20 return self.__length * self.__width
21 def show_area(self):
22 #提供接口函数
23 return self.__show_area()
24 r1 = Room("Ezhizen",12,12,12)
25 r1.show_area()
26 print("Ezhizen住的面积",area)
View Code
4.自省/反射
1 class A:
2 pass
3 a = A()
4 print(isinstance(a,A)) #判断a是否是A的对象
5 class B(A):
6 pass
7
8 print(issubclass(B,A)) #判断B是否为A的子类
自省:主要是指程序可以访问、检测和修改它本身状态或行为的一种能力.通过字符串的形式操作对象相关的属性
hasattr(obj,name). 判断object中有没有一个name字符串对应的方法或属性
getattr(obj,name,default=None)
setattr(x,y,v). 等价于 x.y= v
delattr(x,y)。等价于 del x.y
1 class Student:
2 def __init__(self,name,age,sex):
3 self.name = name
4 self.age = age
5 self.sex = sex
6 def show_info(self):
7 print("%s的年龄为%s"%(self.name,self.age))
8 s1 = Student("Ezhizen",18,"boy")
9 print(hasattr(s1,"name")) #判断是否存在name这个属性
10 print(getattr(s1,"name")) #获得name属性值
11 print(getattr(s1,"q","error"))
12 setattr(s1,"hobby","tennis") #设置属性
13 print(s1.__dict__)
14 delattr(s1,"hobby") #删除属性
15 print(s1.__dict__)
__setattr__ __getattr__\__delattr__
1 class Foo:
2 x=1
3 def __init__(self,y):
4 self.y = y
5 def __getattr__(self, item):
6 print("你找的属性不存在")
7 def __setattr__(self, key, value):
8 # self.key = value #进入无限递归
9 print("执行setattr方法")
10 self.__dict__[key] = value
11 def __delattr__(self, item):
12 print("执行delattr方法")
13 # del self.item #进入无限递归
14 self.__dict__.pop(item)
15 f = Foo(10) #执行init函数 执行setattr
16 print(f.x) #属性存在时获得该属性值
17 f.q #属性不存在,执行getattr方法
18 del f.y #执行delattr方法
1 class Foo:
2 x=1
3 def __init__(self,y):
4 self.y = y
5 def __getattribute__(self, item):
6 print('1111')
7 raise AttributeError("不存在")
8 def __getattr__(self, item):
9 print("你找的属性不存在")
10
11 def __setattr__(self, key, value):
12 # self.key = value #进入无限递归
13 print("执行setattr方法")
14 self.__dict__[key] = value
15 def __delattr__(self, item):
16 print("执行delattr方法")
17 # del self.item #进入无限递归
18 self.__dict__.pop(item)
19 f = Foo(10) #执行init函数 执行setattr
20 # print(f.x) #属性存在时获得该属性值
21 f.q #属性不存在,执行getattr方法
22 #如果getattribute也存在,先执行getattribute 抛出attributeerror,执行getattr
23 # del f.y #执行delattr方法
View Code