软件质量属性包含:成本,性能,可靠性,安全性,可维护性,可移植性,可伸缩性,可扩展性等python
country='American' def study(): print('study english') class Student(): country = 'China' def __init__(self, ID, NAME, SEX, PROVINCE,country): self.id = ID self.name = NAME self.sex = SEX self.province = PROVINCE self.country = country def search_score(self): print('全局的',country) study() #全局的 print('类里的', Student.country) Student.study(self) #类里的 print('对象的', self.country) #对象有就从自身找,没有就从类中找 self.study() # def study(self): print('study',self.country) s1 = Student('3718818181', 'alex', 'female', 'shanxi','Singapore') s1.search_score() """ 全局的 American study english 类里的 China study Singapore 对象的 Singapore study Singapore """
在obj.name会先从obj本身的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常git
class A: def fa(self): print('from A') def test(self): self.fa() class B(A): def fa(self): print('from B') b=B() b.test() #from B """ 从本身找b.test(),没有找类B,也没有找类A,找到后执行self.fa(), self指的是b对象,而后又从本身找fa(),没有就去类B中找fa(),找到了 因此打印 from B """ class C: def __fa(self): #_C__fa print('from C') def test(self): self.__fa() #slef._C__fa __在定义阶段就会变形 class D(C): def __fa(self): #_D__fa print('from D') d=D() d.test() #from C """ __不能被子类继承和覆盖 """
封装在于明确区份内外, 类的实现者不须要让类的调用者知道具体的实现过程,隔离了复杂度,同时也提高了安全性,类的实现者能够修改封装内的东西而不影响外部调用者的代码。编程
使用构造方法将属性封装到某个具体对象中,而后经过对象直接或者self间接获取被封装的属性,类自己就是一种封装的体现,它将数据与专门操做该数据的功能整合到一块儿。安全
import math class Circle: def __init__(self,radius): #圆的半径radius self.radius=radius @property #被@property装饰的方法,调用的时候能够不用加括号,area=property(area) def area(self): return math.pi * self.radius**2 #计算面积 @property def perimeter(self): return 2*math.pi*self.radius #计算周长 c=Circle(3) print(c.area) print(c.perimeter)
#被property装饰的属性会优先于对象的属性被使用,只有在属性sex定义property后才能定义sex.setter,sex.deleter class People: def __init__(self,name,SEX): self.name=name # self.__sex=SEX #这不调用@sex.setter def sex(self,value):方法 由于设置的是__sex 不是 sex,或者说__sex没有被@property装饰 self.sex=SEX #①由于sex被@property装饰,因此self.sex=SEX是去找@sex.setter def sex(self,value): 方法,而不是给对象赋值 @property def sex(self): return self.__sex #p1.__sex @sex.setter def sex(self,value): print('...') if not isinstance(value,str): raise TypeError('性别必须是字符串类型') self.__sex=value #② male给了value , self.__sex='male' @sex.deleter #del p1.sex的时候调用 def sex(self): del self.__sex #del p1.__sex p1=People('alex','male') #会调用 @sex.setter def sex(self,value): 方法是由于__init__中 self.sex=SEX 是给sex设置值了 p1.sex='female' #会调用@sex.setter def sex(self,value): 方法 del p1.sex print(p1.sex) #AttributeError: 'People' object has no attribute '_People__sex'
import time class Date: def __init__(self,year,month,day): self.year=year self.month=month self.day=day @classmethod #把一个方法绑定给类:类.绑定到类的方法(),会把类自己当作第一个参数自动传给绑定到类的方法 def now(cls): #用Date.now()的形式去产生实例,该实例用的是当前时间 t=time.localtime() #获取结构化的时间格式 obj=cls(t.tm_year,t.tm_mon,t.tm_mday) #新建实例而且返回 return obj @classmethod def tomorrow(cls):#用Date.tomorrow()的形式去产生实例,该实例用的是明天的时间 t=time.localtime(time.time()+86400) return cls(t.tm_year,t.tm_mon,t.tm_mday) class EuroDate(Date): def __str__(self): return '年:%s,月:%s,日:%s' %(self.year,self.month,self.day) e1=EuroDate.now() print(e1) e1=EuroDate(1,1,1) print(e1) """ 年:2019,月:3,日:17 年:1,月:1,日:1 """
import time class Date: def __init__(self,year,month,day): self.year=year self.month=month self.day=day @staticmethod def now(): #用Date.now()的形式去产生实例,该实例用的是当前时间 t=time.localtime() #获取结构化的时间格式 obj=Date(t.tm_year,t.tm_mon,t.tm_mday) #新建实例而且返回 return obj @staticmethod def tomorrow():#用Date.tomorrow()的形式去产生实例,该实例用的是明天的时间 t=time.localtime(time.time()+86400) return Date(t.tm_year,t.tm_mon,t.tm_mday) d1=Date.now() print(d1.year,d1.month,d1.day) d2=Date.tomorrow() print(d2.day)
继承是一种建立新类的方式,新建的类能够继承一个或多个父类(python支持多继承),父类又可称为基类或超类,新建的类称为派生类或子类。解决了代码重复的问题服务器
#多态:同一种事物的多种形态,动物分为人类,猪类(在定义角度) class Animal: def run(self): raise AttributeError('子类必须实现这个方法') class People(Animal): def run(self): print('人正在走') class Pig(Animal): def run(self): print('pig is walking') class Dog(Animal): def run(self): print('dog is running') peo1=People() pig1=Pig() d1=Dog() peo1.run() pig1.run() d1.run() #多态性:一种调用方式,不一样的执行效果(多态性) def func(obj): obj.run() func(peo1) func(pig1) func(d1) # peo1.run() # pig1.run() # 多态性依赖于: # 1.继承 # 2. ##多态性:定义统一的接口, def func(obj): #obj这个参数没有类型限制,能够传入不一样类型的值 obj.run() #调用的逻辑都同样,执行的结果却不同 func(peo1) func(pig1)
软件重用的重要方式除了继承以外还有另一种方式,即:组合 组合指的是,在一个类中以另一个类的对象做为数据属性,称为类的组合ide
当类之间有显著不一样,而且较小的类是较大的类所须要的组件时,用组合比较好函数式编程
class Teacher: def __init__(self,name,sex,course): self.name=name self.sex=sex self.course=course class Student: def __init__(self,name,sex,course): self.name=name self.sex=sex self.course=course class Course: def __init__(self,name,price,peroid): self.name=name self.price=price self.period=peroid python_obj=Course('python',15800,'7m') t1=Teacher('egon','male',python_obj) s1=Student('cobila','male',python_obj) print(s1.course.name) print(t1.course.name)
class Animal: def run(self): raise AttributeError('子类必须实现这个方法') def speak(self): raise AttributeError('子类必须实现这个方法') class People(Animal): def run(self): print('人正在走') def speak(self): print('说话') class Pig(Animal): def run(self): print('pig is walking') def speak(self): print('哼哼哼') # peo1=People() # pig1=Pig() # # peo1.run() # pig1.run()
import abc #抽象类:本质仍是类,与普通类额外的特色的是:加了装饰器的函数,子类必须实现他们 class Animal(metaclass=abc.ABCMeta): tag='123123123123123' @abc.abstractmethod def run(self): pass @abc.abstractmethod def speak(self): pass class People(Animal): def run(self): pass def speak(self): pass peo1=People() print(peo1.tag)
经过字符串的形式操做对象相关的属性。python中的一切事物都是对象(均可以使用反射)函数
import sys def add(): print('add') def change(): print('change') def search(): print('search') def delete(): print('delete') this_module=sys.modules[__name__] #获取当前模块 while True: cmd=input('>>:').strip() if not cmd:continue if hasattr(this_module,cmd): func=getattr(this_module,cmd) func() #多分支判断方式1: # func_dic={ # 'add':add, # 'change':change, # 'search':search, # 'delete':delete # } # # while True: # cmd=input('>>:').strip() # if not cmd:continue # if cmd in func_dic: # func=func_dic.get(cmd) # func() #多分支判断方式2: # class Service: # def run(self): # while True: # inp = input('>>: ').strip() # cmd='get a.txt' # cmds = inp.split() # cmds=['get','a.txt'] # if hasattr(self, cmds[0]): # func = getattr(self, cmds[0]) # func(cmds) # # def get(self, cmds): # print('get.......', cmds) # # def put(self, cmds): # print('put.......', cmds) # # obj = Service() # obj.run()
#ftpclient.py class FtpClient: 'ftp客户端,可是还么有实现具体的功能' def __init__(self,addr): print('正在链接服务器[%s]' %addr) self.addr=addr def test(self): print('test') def get(self): print('get------->') #ftpserver.py #服务端同窗能够不用非等着客户端同窗写完代码才去实现 import ftpclient f1=ftpclient.FtpClient('192.168.1.1') if hasattr(f1,'get'): #有就执行没有就执行其余逻辑 func=getattr(f1,'get') func() else: print('其余逻辑')
#!/usr/bin/env python # -*- coding:utf-8 -*- # 先定义类 后产生对象 class Animal: def eat(self): print('is eating') class Student(Animal): # 继承,可继承多个,用mro()查看继承关系 school = 'Peking University' # 类的数据属性 count = 0 def __init__(self, name, age): # 类的函数属性,也就是对象的绑定方法() self.name = name self.age = age Student.count += 1 def learn(self): print('%s is learning' % self.name) def eat(self): # 重写父类方法 print('Wash your hands before eating') # 加入本身新功能 # Peo2.eat(self) #重用父类的方法 # super(Student,self).eat() #重用父类的方法 super().eat() # 重用父类的方法 super是按照mro的顺序查找 """ 类: 一、类的数据属性是全部对象共享的,id都同样 二、类的函数属性是绑定给对象用的,obj.method称为绑定方法,绑定到不一样的对象是不一样的绑定方法,对象调用绑定方式时,会把对象自己看成第一个传入,传给self (绑定到对象的方法的这种自动传值的特征,决定了在类中定义的函数都要默认写一个参数self,self能够是任意名字,可是约定俗成地写出self。 ) 三、__init__方法 (1)、该方法内能够有任意的python代码 (2)、必定不能有返回值 继承: """ print(issubclass(Student, Animal))# 检查Student类是不是Animal类的派生类 # 增 Student.country = 'China' # 删 del Student.country # 改 Student.school = 'Tsinghua University' # 查 print(Student.__dict__) # 查看类的名称空间 print(Student.school) print(Student.learn) print(Student.__mro__) # 查看类的继承关系 print(Student.__bases__) # 查看类的父类 """ 对象: 属性查找顺序:在obj.name会先从obj本身的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常 """ stu = Student('tom', 18) # 实例化一个对象 print(isinstance(stu,Student)) #obj是不是类 cls 的对象 # 增 stu.gender = 'male' # 删 del stu.gender # 改 stu.age = 28 # 查 print(stu.__dict__) print(stu.name) stu.eat() """ super 按照mro的顺序查找 """ class A: def f1(self): print('from A') super().f1() class B: def f1(self): print('from B') class C(A, B): pass print(C.mro()) # [<class '__main__.C'>, # <class '__main__.A'>, # <class '__main__.B'>, # <class 'object'>] c = C() c.f1() # 打印 from A from B """ 封装:类的实现者不须要让类的调用者知道具体的实现过程 """ """ __私有属性,私有方法 (类的定义极端就已经变形了) 这种变形的特色: 一、在类外部没法直接obj.__AttrName 二、在类内部是能够直接使用:obj.__AttrName 三、子类没法覆盖父类__开头的属性 四、在定义阶段就会变形,也就是说__开头的属性(变量和函数)不能被子类继承 由于在定义阶段__属性名就变成了_父类名__属性名。 """ class A: def __foo(self): # _A__foo print('A.foo') def bar(self): print('A.bar') self.__foo() # self._A__foo() class B(A): def __foo(self): # _B__foo print('B.foo') b = B() b.bar() """ @property 类的静态属性,类方法,类的静态方法 在类内部定义的函数,分为两大类: 一:绑定方法:绑定给谁,就应该由谁来调用,谁来调用就回把调用者看成第一个参数自动传入 绑定到对象的方法:在类内定义的没有被任何装饰器修饰的 绑定到类的方法:在类内定义的被装饰器classmethod修饰的方法 二:非绑定方法:没有自动传值这么一说了,就类中定义的一个普通工具,对象和类均可以使用 非绑定方法:不与类或者对象绑定 """ import hashlib, time class Teacher: def __init__(self, name, weight, height): self.name = name self.weight = weight self.height = height self.id = self.create_id() @property # 类的静态属性@property 封装的部分体现 def bmi(self): return self.weight / (self.height ** 2) @classmethod # 绑定到类的方法 def talk(cls): print('is talking') @staticmethod # 非绑定方法 类的静态方法,就是一个普通工具 def create_id(): m = hashlib.md5(str(time.time()).encode('utf-8')) return m.hexdigest() def play(self): # 绑定到对象的方法 print('is playing') t = Teacher('jack', 80, 1.8) print(t.bmi) print(t.id) """ 多态: 不考虑对象的类型,直接使用对象,也就是不一样类的实例调用相同的方法,实现的过程不同。 多态怎么来的? 1,不一样的类先继承基类, 2,而后不一样类的实例调用相同的方法(这个相同的方法是从基类那继承来的) 抽象类: 本质仍是类,于普通类不同的是,加了装饰器的函数,子类必须实现他们,也就是抽象类的方法必需要重写 """ import abc class People(metaclass=abc.ABCMeta): # 抽象类,只能被继承,不能被实例化 @abc.abstractmethod def answer(self): pass class Chinese(People): def answer(self): # 抽象类的方法必需要重写 print('用中文答辩') class English(People): def answer(self): # 抽象类的方法必需要重写 print('use english') chi = Chinese() eng = English() def ans(obj): # 相同的调用方式 obj.answer() ans(chi) # 相同的调用方式 多态 ans(eng) # 相同的调用方式 """ 类的组合: 软件重用的重要方式除了继承以外还有另一种方式,即:组合 组合指的是,在一个类中以另一个类的对象做为数据属性,称为类的组合 """ class Date: def __init__(self, year, mon, day): self.year = year self.mon = mon self.day = day def tell_info(self): print('My birthday is %s-%s-%s' % (self.year, self.mon, self.day)) d = Date(1986, 6, 26) stu2 = Student('rose', 88) stu2.birth = d stu2.birth.tell_info() """ 反射:经过字符串映射到对象的属性 setattr(obj,'sex','male') getattr(obj,'namexxx',None) hasattr(obj,'talk') delattr(obj,'age') """ class Service: def run(self): while True: inp = input('>>: ').strip() # cmd='get a.txt' cmds = inp.split() # cmds=['get','a.txt'] if hasattr(self, cmds[0]): func = getattr(self, cmds[0]) func(cmds) def get(self, cmds): print('get.......', cmds) def put(self, cmds): print('put.......', cmds) obj = Service() # obj.run()