一、组合
class People: school='Harvard' def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender class Student(People): def __init__(self, name, age, gender, stu_id): People.__init__(self, name, age, gender) self.stu_id = stu_id self.courses = [] def choose(self): pass def tell_courses_info(self): for course_obj in self.courses: print("<课程:%s> <价钱:%s> <周期:%s>" % (course_obj.name, course_obj.price, course_obj.period)) class Teacher(People): def __init__(self, name, age, gender, level, salary): People.__init__(self, name, age, gender) self.level = level self.salary = salary self.courses = [] def score(self): pass def tell_courses_info(self): for course_obj in self.courses: print("<课程:%s> <价钱:%s> <周期:%s>" % (course_obj.name, course_obj.price, course_obj.period)) class Course: def __init__(self, name, price, period): self.name = name self.price = price self.period = period def tell_courses_info(self): print("<课程:%s> <价钱:%s> <周期:%s>" % (self.name, self.price, self.period)) stu = Student('张三', 18, 'male', 33, ) tea = Teacher("egon", 18, 'male', 10, 3000) python_obj = Course("python", 33000, "6mons") linux_obj = Course("linux", 20000, "5mons") java_obj=Course('java',30000,'6mons') stu.courses.append(python_obj) stu.courses.append(linux_obj) stu.courses.append(java_obj) tea.courses.append(python_obj) tea.courses.append(linux_obj) tea.courses.append(java_obj) stu.tell_courses_info() tea.tell_courses_info()
# 组合与继承都是为了解决类与类直接冗余问题的 # 继承:is-a # 组合:has-a class People: school = "oldboy" def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender class CourseMixin: def tell_courses_info(self): print("============%s==========" %self.name) for course_obj in self.courses: course_obj.tell_info() class Student(CourseMixin,People): def __init__(self, name, age, gender, stu_id): People.__init__(self, name, age, gender) self.stu_id = stu_id self.courses = [] def choose(self): pass class Teacher(CourseMixin,People): def __init__(self, name, age, gender, level, salary): People.__init__(self, name, age, gender) self.level = level self.salary = salary self.courses = [] def score(self): pass class Course: def __init__(self, name, price, period): self.name = name self.price = price self.period = period def tell_info(self): print("<名字:%s> <价钱:%s> <周期:%s>" %(self.name,self.price,self.period)) stu = Student('张三', 18, 'male', 33, ) tea = Teacher("egon", 18, 'male', 10, 3000) python_obj = Course("python", 33000, "6mons") linux_obj = Course("linux", 20000, "5mons") stu.courses.append(python_obj) stu.courses.append(linux_obj) tea.courses.append(python_obj) # print(stu.courses) # print(tea.courses) # print(stu.courses[0]) stu.tell_courses_info() tea.tell_courses_info()
二、多态、鸭子类型
(一)多态
import abc class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod def speak(self): pass class People(Animal): def speak(self): print('哈哈哈') pass class Dog(Animal): def speak(self): print('旺旺旺') class Pig(Animal): def speak(self): print('哼哼哼') obj1=People() obj2=Dog() obj3=Pig() print('人高兴时的叫声:') obj1.speak() print('狗高兴时的叫声:') obj2.speak() print('猪高兴时的叫声:') obj3.speak()
(二)鸭子类型
什么是鸭子类型? “当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。” 我们并不关心对象是什么类型,到底是不是鸭子,只关心行为。 比如在python中,有很多file-like的东西,比如StringIO,GzipFile,socket。它们有很多相同的方法,我们把它们当作文件使用。 又比如list.extend()方法中,我们并不关心它的参数是不是list,只要它是可迭代的,所以它的参数可以是list/tuple/dict/字符串/生成器等. 鸭子类型在动态语言中经常使用,非常灵活,使得python不像java那样专门去弄一大堆的设计模式。 例子如下: # python推崇鸭子类型 class Animal: def speck(self): pass class People: def speak(self): print("啊啊啊") class Dog: def speak(self): print('汪汪汪') class Pig: def speak(self): print('哼哼哼') def in_the_forest(animal): animal.speak() obj1 = People() obj2 = Dog() obj3 = Pig() for x in [obj1,obj2,obj3]: in_the_forest(x)
三、绑定方法与非绑定方法
# 1、绑定方法 # 特殊之处:与调用者捆绑,应该由捆绑的调用者里调用,调用者在调用时会将自身当作第一个参数传入 # 1.1 绑定给对象的方法:类中定义的函数默认都是绑定给对象的,应该由对象来调用,会对象自己当作第一个参数传入 # class People: # def __init__(self, name, age): # self.name = name # self.age = age # # def tell_info(self): # print("<%s:%s>" %(self.name, self.age)) # # obj = People("egon",18) # obj.tell_info() # 1.2 绑定给类的方法:在类中定义的函数上添加装饰器classmethod,应该由类来调用,会类自己当作第一个参数传入 # class People: # def __init__(self, name, age): # self.name = name # self.age = age # # def tell_info(self): # print("<%s:%s>" %(self.name, self.age)) # # @classmethod # def f1(cls): # print(cls) # obj = People("egon",18) # obj.tell_info() # print(People.tell_info) # print(People.f1) # People.tell_info() # People.f1() # 2、非绑定方法 # 特殊之处:不予任何人捆绑,谁都可以来调用,就是一个普通函数,没有自动传参的效果 # 非绑定方法:在类中定义的函数上添加装饰器staticmethod,谁都可以来调用,就是一个普通函数,没有自动传参的效果 # class People: # def __init__(self, name, age): # self.name = name # self.age = age # # def tell_info(self): # print("<%s:%s>" %(self.name, self.age)) # # @classmethod # def f1(cls): # print(cls) # # @staticmethod # def f2(x,y): # print(x,y) # # # obj=People('egon',18) # # # print(People.f2) # # print(obj.f2) # # People.f2(1,2) # obj.f2(3,4) # 应用场景 import settings import uuid class Mysql: def __init__(self, ip, port): self.id = self.create_id() self.ip = ip self.port = port def tell_info(self): print("<%s:%s>" % (self.ip, self.port)) @classmethod def from_conf(cls): return cls(settings.IP, settings.PORT) @staticmethod def create_id(): return uuid.uuid4() obj1 = Mysql('172.168.10.11', 3030) # obj2 = Mysql.from_conf() # print(obj2.__dict__) # print(Mysql.create_id()) # print(obj2.create_id())
四、反射
class People: x=1111 def __init__(self, name): self.name = name obj = People("egon") # res = hasattr(obj, "name") # "name" in obj.__dict__ # print(res) # res = getattr(obj, "name") # obj.name # print(res) # setattr(obj,"name","EGON") # obj.name="EGON" # print(obj.name) # delattr(obj,"name") # print(obj.__dict__) # print(hasattr(People,"x")) class Ftp: def get(self): print('get...') def put(self): print('put...') obj=Ftp() cmd=input('>>>: ') # get if hasattr(obj,cmd): f=getattr(obj,cmd) print(f) f()
五、内置方法
# __方法__:称之为内置方法,定义在类内部,都不是直接调用的,都是在满足某种条件下自动触发执行的 # __str__:在打印对象时自动触发执行,将返回值当作打印的结果输出,注意返回值必须是字符串类型 # class People: # def __init__(self, name, age, gender): # self.name = name # self.age = age # self.gender = gender # # def __str__(self): # return "<%s:%s:%s>" %(self.name,self.age,self.gender) # # obj = People("egon",18,'male') # print(obj) # print(obj.__str__()) # len(obj) # obj.__len__ # l=[111,222,333] # l=list([111,222,333]) # print(l) # x=10 # x=int(10) # print(x) # __del__:删除对象内存空间之前,自动触发执行,用于回收操作系统资源 # class Bar: # pass # # class Foo(Bar): # def __init__(self, x, y,filepath): # self.x = x # self.y = y # self.f=open(filepath,mode='r',encoding='utf-8') # # # def __del__(self): # # print('回收系统资源的代码') # # self.f.close() # # obj=Foo(111,222,'a.txt') # # del obj # # print('============main===============') # # # print(isinstance(obj,Foo)) # print(isinstance(10,int)) # # print(issubclass(Foo,Bar)) # # # class Foo: # pass # # obj=Foo() # print(hasattr(obj,"__str__")) # print(hasattr(obj,"__del__"))
六、套接字编程
""" C/S架构 client--------互联网--------server B/S browser--------互联网--------server 服务端: 1、一直对外提供服务 2、服务端的必须绑定一个固定的地址 3、并发能力 网络存在的意义? 互联网存在的意义让通信变得方便 什么是互联网? 网络=底层物理连接介质+互联网通信协议 ip+mac=》标识全世界范围内独一无二的一台计算机 ip+mac+port=》标识全世界范围内独一无二的一个基于网络通信的应用软件 因为ARP协议的存在,可以将ip解析成mac,所以: ip+port=》标识全世界范围内独一无二的一个基于网络通信的应用软件 """
七、基于TCP的套接字程序
import socket phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 流式协议=》tcp phone.connect(("127.0.0.1",8080)) phone.send("hello".encode('utf-8')) data=phone.recv(1024) print(data) phone.close()
import socket # 1、买电话 phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 流式协议=》tcp # print(phone) # 2、插电话卡 phone.bind(("127.0.0.1",8080)) # 3、开机 phone.listen(5) print("starting:%s:%s" %("127.0.0.1",8080)) # 4、等电话连接 conn,client_addr=phone.accept() # print(conn,client_addr) print(client_addr) # 5、收/发消息 data=conn.recv(1024) # 最大接收1024个字节 print(data) conn.send(data.upper()) # 6、挂电话 conn.close() # 7、关机 phone.close()
八、加上循环的套接字
import socket phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 流式协议=》tcp phone.connect(("127.0.0.1",8081)) while True: msg=input('>>: ').strip() # msg='' if len(msg) == 0:continue phone.send(msg.encode('utf-8')) # print('has send=====>') data=phone.recv(1024) # print('has recv=====>') print(data) phone.close()
import socket phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 流式协议=》tcp # phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加 phone.bind(("127.0.0.1",8081)) phone.listen(5) print("starting:%s:%s" %("127.0.0.1",8081)) # 链接循环 while True: conn,client_addr=phone.accept() print(client_addr) # 通信循环 while True: try: # 针对windows系统 data=conn.recv(1024) # 最大接收1024个字节 if len(data) == 0:break # 针对linux系统 print(data) conn.send(data.upper()) except Exception: break conn.close() phone.close()
九、远程执行命令的程序
import socket phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 流式协议=》tcp phone.connect(("127.0.0.1",8082)) while True: cmd=input('>>: ').strip() # msg='' if len(cmd) == 0:continue phone.send(cmd.encode('utf-8')) data=phone.recv(1024) print(data.decode('gbk')) phone.close()
import socket import subprocess phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 流式协议=》tcp phone.bind(("127.0.0.1",8082)) phone.listen(5) # 链接循环 while True: conn,client_addr=phone.accept() print(client_addr) # 通信循环 while True: try: # 针对windows系统 cmd=conn.recv(1024) # 最大接收1024个字节 if len(cmd) == 0:break # 针对linux系统 obj = subprocess.Popen( cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) conn.send(obj.stdout.read()) conn.send(obj.stderr.read()) except Exception: break conn.close() phone.close()