my python day6

一、类的相关知识

类:把一类事物具有相同特征和动作整合到一起

对象:基于类而创建的一个具体的实例

实例化:类生成对象的过程

关键字 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

 

posted @ 2019-07-18 22:02  Ezhizen  阅读(140)  评论(0编辑  收藏  举报