第三模块 面向对象&网络编程基础 视频课程代码笔记
面向对象
1 面向过程编程
面向过程:核心是过程二字,过程指的是解决问题的步骤,设计一条流水线,机械式的思维方式
优点:复杂的问题流程化,进而简单化
缺点:可扩展性差
''' 面向过程:核心是过程二字,过程指的是解决问题的步骤,设计一条流水线,机械式的思维方式 优点:复杂的问题流程化,进而简单化 缺点:可扩展性差 ''' import json import re def interactive(): name=input('>>: ').strip() pwd=input('>>: ').strip() email=input('>> ').strip() return { 'name':name, 'pwd':pwd, 'email':email } def check(user_info): is_valid=True if len(user_info['name']) == 0: print('用户名不能为空') is_valid=False if len(user_info['pwd']) < 6: print('密码不能少于6位') is_valid=False if not re.search(r'@.*?\.com$',user_info['email']): print('邮箱格式不合法') is_valid=False return { 'is_valid':is_valid, 'user_info':user_info } def register(check_info): if check_info['is_valid']: with open('db.json','w',encoding='utf-8') as f: json.dump(check_info['user_info'],f) def main(): user_info=interactive() check_info=check(user_info) register(check_info) if __name__ == '__main__': main()
2 面向对象编程
在现实世界中: 对象1:王二丫 特征: 学校='luffycity' 名字='王二丫' 性别='女' 年龄=18 技能: 学习 吃饭 睡觉 对象2:李三炮 特征: 学校='luffycity' 名字='李三炮' 性别='男' 年龄=38 技能: 学习 吃饭 睡觉 对象3:张铁蛋 特征: 学校='luffycity' 名字='张铁蛋' 性别='男' 年龄=48 技能: 学习 吃饭 睡觉 总结现实中路飞学院的学生类: 相似的特征 学校='luffycity' 相似的技能 学习 吃饭 睡觉
#先定义类 class LuffyStudent: school='luffycity' def learn(self): print('is learning') def eat(self): print('is sleeping') #后产生对象 stu1=LuffyStudent() stu2=LuffyStudent() stu3=LuffyStudent() print(stu1) print(stu2) print(stu3)

3 如何使用类
#先定义类 class LuffyStudent: school='luffycity' #数据属性 def learn(self): #函数属性 print('is learning') def eat(self): #函数属性 print('is sleeping') #查看类的名称空间 #print(LuffyStudent.__dict__) #print(LuffyStudent.__dict__['school']) #print(LuffyStudent.__dict__['learn']) #查 #print(LuffyStudent.school) #LuffyStudent.__dict__['school'] #print(LuffyStudent.learn) #LuffyStudent.__dict__['learn'] #增 LuffyStudent.county='China' # print(LuffyStudent.__dict__) print(LuffyStudent.county) #删 del LuffyStudent.county #改 LuffyStudent.school='Luffycity'
类在执行时,定义阶段就执行
在类里面除了函数(函数属性)、变量(数据属性) ,也可以写其他的
4 __init__方法
class LuffyStudent: school='luffycity' # stu1, '王二丫', '女', 18 def __init__(self,name,sex,age): self.Name=name self.Sex=sex self.Age=age #stu1.Name='王二丫' #stu1.Sex='女' #stu1.Age=18 def learn(self): print('is learning') def eat(self): print('is sleeping') #后产生对象 stu1=LuffyStudent('王二丫','女',18) #LuffyStudent.__init__(stu1,'王二丫','女',18) #加上__init__方法后,实例化的步骤 # 1、先产生一个空对象stu1 # 2、LuffyStudent.__init__(stu1,'王二丫','女',18) #查 print(stu1.__dict__) #print(stu1.Name) #print(stu1.Sex) #print(stu1.Age) #改 # stu1.Name='李二丫' # print(stu1.__dict__) # print(stu1.Name) #删除 # del stu1.Name # print(stu1.__dict__) # # #增 # stu1.class_name='python开发' # print(stu1.__dict__) # # # stu2=LuffyStudent('李三炮','男',38) #Luffycity.__init__(stu2,'李三炮','男',38) # print(stu2.__dict__) # print(stu2.Name) # print(stu2.Age) # print(stu2.Sex)
5 属性查找
''' 在现实世界中: 对象1:王二丫 特征: 学校='luffycity' 名字='王二丫' 性别='女' 年龄=18 技能: 学习 吃饭 睡觉 对象2:李三炮 特征: 学校='luffycity' 名字='李三炮' 性别='男' 年龄=38 技能: 学习 吃饭 睡觉 对象3:张铁蛋 特征: 学校='luffycity' 名字='张铁蛋' 性别='男' 年龄=48 技能: 学习 吃饭 睡觉 总结现实中路飞学院的学生类: 相似的特征 学校='luffycity' 相似的技能 学习 吃饭 睡觉 '''
x='global' class LuffyStudent: school='luffycity' def __init__(self,name,sex,age): self.Name=name self.Sex=sex self.Age=age #stu1.Name='王二丫' #stu1.Sex='女' #stu1.Age=18 def learn(self,x): print('%s is learning %s' %(self.Name,x)) def eat(self): print('%s is sleeping' %self.Name) #后产生对象 stu1=LuffyStudent('王二丫','女',18) stu2=LuffyStudent('李三炮','男',38) stu3=LuffyStudent('张铁蛋','男',48) # print(stu1.__dict__) # print(stu2.__dict__) # print(stu3.__dict__) #对象:特征与技能的结合体 #类:类是一系列对象相似的特征与相似的技能的结合体 #类中的数据属性:是所以对象共有的 # print(LuffyStudent.school,id(LuffyStudent.school)) # # print(stu1.school,id(stu1.school)) # print(stu2.school,id(stu2.school)) # print(stu3.school,id(stu3.school)) #类中的函数属性:是绑定给对象使用的,绑定到不同的对象是不同的绑定方法,对象调用绑定方式时,会把对象本身当作第一个传入,传给self # print(LuffyStudent.learn) # LuffyStudent.learn(stu1) # LuffyStudent.learn(stu2) # LuffyStudent.learn(stu3) # print(stu1.learn) # stu1.learn(1) #learn(stu1,1) # print(stu2.learn) # print(stu3.learn) # stu2.learn(2) # stu3.learn(3) #先从函数的局部去找,然后往上级找 # stu1.x='from stu1' # LuffyStudent.x='from Luffycity class' print(stu1.__dict__) print(stu1.x)
6 补充
#python一切皆对象,在python3里统一类类与类型的概念
# print(type([1,2])) # print(list) class LuffyStudent: school='luffycity' def __init__(self,name,sex,age): self.Name=name self.Sex=sex self.Age=age #stu1.Name='王二丫' #stu1.Sex='女' #stu1.Age=18 def learn(self,x): print('%s is learning %s' %(self.Name,x)) def eat(self): print('%s is sleeping' %self.Name) # print(LuffyStudent) l1=[1,2,3] #l=list([1,2,3]) l2=[] #l=list([1,2,3]) # l1.append(4) #list.append(l1,4) list.append(l1,4) print(l1)
7 面向对象小结
class Chinese: county='China' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def eat(self): print('%s is eating' %self.name) p1=Chinese('egon',18,'male') p2=Chinese('alex',38,'female') p3=Chinese('wpq',48,'female') # print(p1.county) # print(p2.county) # print(p3.county) p1.eat() p2.eat() p3.eat()
8 练习
''' 练习1:编写一个学生类,产生一堆学生对象, (5分钟) 要求: 有一个计数器(属性),统计总共实例了多少个对象 '''
类属性
class Student: school='luffycity' count=0 def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex # self.count+=1 Student.count+=1 def learn(self): print('%s is learing' %self.name) stu1=Student('alex','male',38) stu2=Student('jinxing','female',78) stu3=Student('egon','male',18) # # print(Student.count) # print(stu1.count) # print(stu2.count) # print(stu3.count) # print(stu1.__dict__) # print(stu2.__dict__) # print(stu3.__dict__)
对象之间交互
''' 练习2:模仿LoL定义两个英雄类, (10分钟) 要求: 英雄需要有昵称、攻击力、生命值等属性; 实例化出两个英雄对象; 英雄之间可以互殴,被殴打的一方掉血,血量小于0则判定为死亡。 '''
class Garen: camp = 'Demacia' def __init__(self, nickname, life_value, aggresivity): self.nickname = nickname self.life_value = life_value self.aggresivity = aggresivity def attack(self, enemy): enemy.life_value -= self.aggresivity # r1.life_value-=g1.aggresivity class Riven: camp = 'Noxus' def __init__(self, nickname, life_value, aggresivity): self.nickname = nickname self.life_value = life_value self.aggresivity = aggresivity def attack(self, enemy): enemy.life_value -= self.aggresivity g1 = Garen('草丛伦', 100, 30) r1 = Riven('可爱的锐雯雯', 80, 50) print(r1.life_value) g1.attack(r1) print(r1.life_value)
9 继承
class ParentClass1: pass class ParentClass2: pass class SubClass1(ParentClass1): pass class SubClass2(ParentClass1,ParentClass2): pass print(SubClass1.__bases__) print(SubClass2.__bases__) # class Hero: # x=3 # def __init__(self,nickname,life_value,aggresivity): # self.nickname=nickname # self.life_value=life_value # self.aggresivity=aggresivity # def attack(self,enemy): # enemy.life_value-=self.aggresivity # # class Garen(Hero): # # x=2 # pass # class Riven(Hero): # pass # g1=Garen('刚们',29,30) # # print(g1.nickname,g1.life_value,g1.aggresivity) # # g1.x=1 # # print(g1.x)
#属性查找小练习 class Foo: def f1(self): print('from Foo.f1') def f2(self): print('from Foo.f2') self.f1() #b.f1() class Bar(Foo): def f1(self): print('from Bar.f1') b=Bar() # print(b.__dict__) b.f2() #from Bar.f1
10 派生
class Hero: def __init__(self,nickname,life_value,aggresivity): self.nickname=nickname self.life_value=life_value self.aggresivity=aggresivity def attack(self,enemy): enemy.life_value-=self.aggresivity class Garen(Hero): camp='Demacia' def attack(self,enemy): print('from Garen Class') class Riven(Hero): camp='Noxus' g=Garen('草丛伦',100,30) r=Riven('锐雯雯',80,50) # print(g.camp) # g.attack(r) # print(r.life_value) g.attack(r)
11 继承的实现原理
在python 2中,经典类采用的是深度优先查找法, 新式类采用的是广度优先
在python 3中,无论是经典类,还是新式类,都是按广度优先查找
Python 2.x中默认都是经典类,只有显式继承了object才是新式类
Python 3.x中默认都是新式类,不必显式的继承object
*之所以在python3中全改成了广度优先,是因为用深度优先在某些特殊情况下,会出现bug.


# python2中才分 #1、新式类 #2、经典类 #在python2中-》经典类:没有继承object的类,以及它的子类都称之为经典类 class Foo: pass class Bar(Foo): pass #在python2中-》新式类:继承object的类,以及它的子类都称之为新式类 class Foo(object): pass class Bar(Foo): pass #在python3中-》统一都是新式类:一个类没有继承object类,默认就继承object class Foo(): # class Foo: #class Foo(object): # 都一样 pass print(Foo.__bases__)

#验证多继承情况下的属性查找 class A: # def test(self): # print('from A') pass class B(A): # def test(self): # print('from B') pass class C(A): # def test(self): # print('from C') pass class D(B): # def test(self): # print('from D') pass class E(C): # def test(self): # print('from E') pass class F(D,E): # def test(self): # print('from F') pass #F,D,B,E,C,A print(F.mro()) f=F() f.test()

[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
经典类没有提供mro方法
12 在子类中重用父类的属性
#在子类派生出的新的方法中重用父类的方法,有两种实现方式
class Hero: def __init__(self,nickname,life_value,aggresivity): self.nickname=nickname self.life_value=life_value self.aggresivity=aggresivity def attack(self,enemy): enemy.life_value-=self.aggresivity class Garen(Hero): camp='Demacia' def attack(self,enemy): Hero.attack(self,enemy) #指名道姓 print('attack from Garen Class') class Riven(Hero): camp='Noxus' g=Garen('草丛伦',100,30) r=Riven('锐雯雯',80,50) print(r.life_value) g.attack(r) print(r.life_value) # 80 # attack from Garen Class # 50
# class Hero: # def __init__(self,nickname,life_value,aggresivity): # self.nickname=nickname # self.life_value=life_value # self.aggresivity=aggresivity # def attack(self,enemy): # enemy.life_value-=self.aggresivity # class Garen(Hero): # camp='Demacia' # # def __init__(self,nickname,life_value,aggresivity,weapon): # # self.nickname=nickname # # self.life_value=life_value # # self.aggresivity=aggresivity # Hero.__init__(self,nickname,life_value,aggresivity) # # self.weapon=weapon # # def attack(self,enemy): # Hero.attack(self,enemy) #指名道姓 # print('from Garen Class') # # # g=Garen('草丛伦',100,30,'金箍棒') # # print(g.__dict__)
class Hero: def __init__(self, nickname, life_value, aggresivity): self.nickname = nickname self.life_value = life_value self.aggresivity = aggresivity def attack(self, enemy): enemy.life_value -= self.aggresivity class Garen(Hero): camp = 'Demacia' def __init__(self, nickname, life_value, aggresivity, weapon): # self.nickname=nickname # self.life_value=life_value # self.aggresivity=aggresivity # super(Garen,self).__init__(nickname,life_value,aggresivity) # python2里面这样写 super().__init__(nickname, life_value, aggresivity) # python3里面可以简写 self.weapon = weapon def attack(self, enemy): # super(Garen, self).attack(enemy) # 依赖继承 python2里面这样写 super().attack(enemy) # 复用父类的方法,python3 的简写写法 print('from Garen Class') print(enemy.life_value) class Riven(Hero): camp = 'Noxus' g = Garen('草丛伦', 100, 30, '金箍棒') r = Riven('瑞文',80,50) print(g.__dict__) g.attack(r) # {'nickname': '草丛伦', 'life_value': 100, 'aggresivity': 30, 'weapon': '金箍棒'} # from Garen Class # 50
class A: def f1(self): print('from A') super().f1() # 依赖继承。是基于子类C的mro去往后找 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()
13 组合
给一个类的实例对象,增加另一个类对象作为属性。达到类的组合
实现调用另一个类的属性
class People: school='luffycity' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex class Teacher(People): def __init__(self,name,age,sex,level,salary,): super().__init__(name,age,sex) self.level=level self.salary=salary def teach(self): print('%s is teaching' %self.name) class Student(People): def __init__(self, name, age, sex, class_time,): super().__init__(name,age,sex) self.class_time=class_time def learn(self): print('%s is learning' % self.name) class Course: def __init__(self,course_name,course_price,course_period): self.course_name = course_name self.course_price = course_price self.course_period = course_period def tell_info(self): print('课程名<%s> 课程价钱<%s> 课程周期<%s>' %(self.course_name,self.course_price,self.course_period)) class Date: def __init__(self,year,mon,day): self.year=year self.mon=mon self.day=day def tell_info(self): print('%s-%s-%s' %(self.year,self.mon,self.day)) # teacher1=Teacher('alex',18,'male',10,3000,) # teacher2=Teacher('egon',28,'male',30,3000,) # python=Course('python',3000,'3mons') # linux=Course('linux',2000,'4mons') # print(python.course_name) # teacher1.course=python # teacher2.course=python #老师与课程 # print(python) # print(teacher1.course) # print(teacher2.course) # print(teacher1.course.course_name) # print(teacher2.course.course_name) # teacher1.course.tell_info() # student1=Student('张三',28,'female','08:30:00') # student1.course1=python # student1.course2=linux # student1.course1.tell_info() # student1.course2.tell_info() # student1.courses=[] # student1.courses.append(python) # student1.courses.append(linux) student1=Student('张三',28,'female','08:30:00') d=Date(1988,4,20) python=Course('python',3000,'3mons') student1.birh=d student1.birh.tell_info() student1.course=python student1.course.tell_info()
14 抽象类
import abc # 抽象类 class Animal(metaclass=abc.ABCMeta): #只能被继承,不能被实例化 all_type='animal' @abc.abstractmethod def run(self): pass @abc.abstractmethod def eat(self): pass # animal=Animal() class People(Animal): def run(self): print('people is running') def eat(self): print('people is eating') class Pig(Animal): def run(self): print('people is walking') def eat(self): print('people is eating') class Dog(Animal): def run(self): print('people is walking') def eat(self): print('people is eating') peo1=People() pig1=Pig() dog1=Dog() # # peo1.eat() pig1.eat() dog1.eat() print(peo1.all_type)
15 多态与多态性
#多态:同一类事物的多种形态 import abc class Animal(metaclass=abc.ABCMeta): #同一类事物:动物 @abc.abstractmethod def talk(self): pass class People(Animal): #动物的形态之一:人 def talk(self): print('say hello') class Dog(Animal): #动物的形态之二:狗 def talk(self): print('say wangwang') class Pig(Animal): #动物的形态之三:猪 def talk(self): print('say aoao') class Cat(Animal): def talk(self): print('say miamiao') #多态性:指的是可以在不考虑对象的类型的情况下而直接使用对象 peo1=People() dog1=Dog() pig1=Pig() cat1=Cat() # peo1.talk() # dog1.talk() # pig1.talk() def func(animal): animal.talk() func(peo1) func(pig1) func(dog1) func(cat1)
16 鸭子类型
# class Disk: # def read(self): # print('disk read') # # def write(self): # print('disk write') # # # class Text: # def read(self): # print('text read') # # def write(self): # print('text write') # # # # # f=open(...) # # f.read() # # f.write() # # disk=Disk() # text=Text() # # disk.read() # disk.write() # # text.read() # text.write() #序列类型:列表list,元祖tuple,字符串str l=list([1,2,3]) t=tuple(('a','b')) s=str('hello') # print(l.__len__()) # print(t.__len__()) # print(s.__len__()) # def len(obj): # return obj.__len__() print(len(l)) print(len(t)) print(len(s)) # 不一定要一个抽象类来继承 # 只要做的像鸭子,看起来像鸭子,就是鸭子
17 封装之如何实现属性的隐藏
class A: __x = 1 # _A__x=1 def __init__(self, name): self.__name = name # self._A__name=name def __foo(self): # def _A__foo(self): print('run foo') def bar(self): self.__foo() # self._A__foo() print('from bar') print(A.__dict__) # print(A.__x) # AttributeError: type object 'A' has no attribute '__x' # print(A.__foo) a=A('egon') # a._A__foo() # 访问隐藏的属性 # a._A__x # print(a.__name) #a.__dict__['__name'] # print(a.__dict__) a.bar() ''' 这种变形的特点: 1、在类外部无法直接obj.__AttrName 2、在类内部是可以直接使用:obj.__AttrName 3、子类无法覆盖父类__开头的属性 '''
class Foo: def __func(self): #_Foo__func print('from foo') class Bar(Foo): def __func(self): #_Bar__func print('from bar') b=Bar() # b.func() #调用失败 # b._Bar__func()
class B: __x = 1 def __init__(self, name): self.__name = name # self._B__name=name # 验证问题一: # print(B._B__x) # 不要去这样做 # 验证问题二: # __name 只在类定义的时候发生,成为隐藏属性。且只发生一次 B.__y = 2 # 在类定义后,不再发生成为隐藏 print(B.__dict__) # b=B('egon') # print(b.__dict__) # # b.__age=18 # print(b.__dict__) # print(b.__age)
# 验证问题三: class A: def foo(self): print('A.foo') def bar(self): print('A.bar') self.foo() # b.foo() class B(A): def foo(self): print('B.foo') b = B() b.bar() 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()
18 封装的意义
一:封装数据属性:明确的区分内外,控制外部对隐藏的属性的操作行为
class People: def __init__(self,name,age): self.__name=name self.__age=age def tell_info(self): print('Name:<%s> Age:<%s>' %(self.__name,self.__age)) def set_info(self,name,age): if not isinstance(name,str): print('名字必须是字符串类型') return if not isinstance(age,int): print('年龄必须是数字类型') return self.__name=name self.__age=age p=People('egon',18) p.tell_info() p.set_info('EGON',38) p.tell_info() p.set_info(123,38) p.set_info('egon','38') p.tell_info()
二、 封装方法:隔离复杂度
class ATM: def __card(self): print('插卡') def __auth(self): print('用户认证') def __input(self): print('输入取款金额') def __print_bill(self): print('打印账单') def __take_money(self): print('取款') def withdraw(self): self.__card() self.__auth() self.__input() self.__print_bill() self.__take_money() a=ATM() a.withdraw()
19 封装与扩展性
class Room: def __init__(self,name,owner,weight,length,height): self.name=name self.owner=owner self.__weight=weight self.__length=length self.__height=height def tell_area(self): return self.__weight * self.__length * self.__height r=Room('卫生间','alex',10,10,10) # print(r.tell_area()) print(r.tell_area())
20 property的使用
''' BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解) 成人的BMI数值: 过轻:低于18.5 正常:18.5-23.9 过重:24-27 肥胖:28-32 非常肥胖, 高于32 体质指数(BMI)=体重(kg)÷身高^2(m) EX:70kg÷(1.75×1.75)=22.86 '''
class People: def __init__(self, name, weight, height): self.name = name self.weight = weight self.height = height @property # 将函数变为属性 def bmi(self): return self.weight / (self.height ** 2) p = People('egon', 75, 1.81) # p.bmi=p.weight / (p.height ** 2) # print(p.bmi) # print(p.bmi()) # print(p.bmi) p.height=1.82 print(p.bmi) # p.bmi=3333 #报错AttributeError: can't set attribute
class People: def __init__(self, name): self.__name = name @property def name(self): # print('getter') return self.__name @name.setter def name(self, val): # print('setter',val) if not isinstance(val, str): print('名字必须是字符串类型') return # 退出 self.__name = val @name.deleter def name(self): print('deleter') print('不允许删除') p = People('egon') # print(p.get_name()) # print(p.name) # p.name # p.name='EGON' # p.name=123 # print(p.name) del p.name
21 绑定方法与非绑定方法介绍
在类内部定义的函数,分为两大类:
一:绑定方法:绑定给谁,就应该由谁来调用,谁来调用就回把调用者当作第一个参数自动传入
- 绑定到对象的方法:在类内定义的没有被任何装饰器修饰的
- 绑定到类的方法:在类内定义的被装饰器classmethod修饰的方法
二:非绑定方法:没有自动传值这么一说了,就类中定义的一个普通工具,对象和类都可以使用
非绑定方法:不与类或者对象绑定
class Foo: def __init__(self, name): self.name = name def tell(self): print('名字是%s' % self.name) @classmethod def func(cls): # cls=Foo print(cls) @staticmethod # 普通函数 def func1(x, y): print(x + y) f = Foo('egon') # print(Foo.tell) # Foo.tell(f) # print(f.tell) #<bound method Foo.tell of <__main__.Foo object at 0x000002284B38F6A0>> # f.tell() print(Foo.func) # <bound method Foo.func of <class '__main__.Foo'>> # Foo.func() print(Foo.func1) # <function Foo.func1 at 0x00000172864E36A8> # print(f.func1) # Foo.func1(1,2) # f.func1(1,3)
22 绑定方法与非绑定方法应用
import settings import hashlib import time class People: def __init__(self, name, age, sex): self.id = self.create_id() self.name = name self.age = age self.sex = sex def tell_info(self): # 绑定到对象的方法 print('Name:%s Age:%s Sex:%s' % (self.name, self.age, self.sex)) @classmethod def from_conf(cls): obj = cls( # 实例化一个对象 settings.name, settings.age, settings.sex ) return obj # 返回一个对象 @staticmethod def create_id(): m = hashlib.md5(str(time.time()).encode('utf-8')) return m.hexdigest() p=People('egon',18,'male') # 绑定给对象,就应该由对象来调用,自动将对象本身当作第一个参数传入 p.tell_info() #tell_info(p) # 绑定给类,就应该由类来调用,自动将类本身当作第一个参数传入 p = People.from_conf() # from_conf(People) p.tell_info() # 非绑定方法,不与类或者对象绑定,谁都可以调用,没有自动传值一说 p1=People('egon1',18,'male') p2=People('egon2',28,'male') p3=People('egon3',38,'male') print(p1.id) print(p2.id) print(p3.id)
23 反射
# 反射:通过字符串映射到对象的属性 class People: country = 'China' def __init__(self, name, age): self.name = name self.age = age def talk(self): print('%s is talking' % self.name) obj = People('egon', 18) # print(obj.name) #obj.__dict__['name'] # print(obj.talk) # choice=input('>>: ') #choice='name' # print(obj.choice) #print(obj.'name') print(hasattr(obj, 'name')) # obj.name #obj.__dict__['name'] print(hasattr(obj, 'talk')) # obj.talk # print(getattr(obj,'namexxx',None)) print(getattr(obj, 'talk', None)) # 如果没有改属性或者方法,就返回None setattr(obj,'sex','male') #obj.sex='male' print(obj.sex) delattr(obj,'age') #del obj.age print(obj.__dict__) print(getattr(People,'country')) #People.country 同样适用于类
# 反射的应用: class Service: def run(self): while True: inp=input('>>: ').strip() #cmd='get a.txt' cmds=inp.split() #cmds=['get','a.txt'] # print(cmds) 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()
24 内置方法
#item系列 class Foo: #Dict def __init__(self,name): self.name=name def __getitem__(self, item): #item='namexxx' # print('getitem...') return self.__dict__.get(item) def __setitem__(self, key, value): # print('setitem...') # print(key,value) self.__dict__[key]=value def __delitem__(self, key): # print('delitem...') # print(key) del self.__dict__[key] obj=Foo('egon') print(obj.__dict__) #查看属性: # obj.属性名 # print(obj['namexxx']) #obj.name #设置属性: # obj.sex='male' # obj['sex']='male' # print(obj.__dict__) # print(obj.sex) #删除属性 # del obj.name # 之前的操作 # del obj['name'] # 现在的操作 # # print(obj.__dict__)
#__str__方法: d=dict({'name':'egon'}) print(isinstance(d,dict)) print(d) class People: def __init__(self,name,age): self.name=name self.age=age def __str__(self): # print('====>str') return '<name:%s,age:%s>' %(self.name,self.age) obj=People('egon',18) print(obj) #res=obj.__str__()
回收操作系统资源
# __del__ # f=open('settings.py') # f.read() # f.close() #回收操作系统的资源 # print(f) # f.read() class Open: def __init__(self, filename): print('open file.......') self.filename = filename def __del__(self): print('回收操作系统资源:self.close()') f = Open('settings.py') # del f #f.__del__() print('----main------') # del f #f.__del__()
在对象被删除的时候,会自动先触发执行__del__
25 元类介绍
# 储备知识exec # 参数1:字符串形式的命令 # 参数2:全局作用域(字典形式),如果不指定默认就使用globals() # 参数3:局部作用域(字典形式),如果不指定默认就使用locals() g = { 'x': 1, 'y': 2 } l = {} exec(""" global x,m x=10 m=100 z=3 """, g, l) # 三个参数,g是全局,l是局部 print(g) # 全局的 print(l) # {'z': 3}
# 一切皆对象,对象可以怎么用? # 1、都可以被引用,x=obj # 2、都可以当作函数的参数传入 # 3、都可以当作函数的返回值 # 4、都可以当作容器类的元素,l=[func,time,obj,1] 存多个值 # 类也是对象,Foo=type(....) class Foo: pass obj=Foo() print(type(obj)) print(type(Foo)) class Bar: pass print(type(Bar))
#产生类的类称之为元类,默认所以用class定义的类,他们的元类是type #定义类的两种方式: #方式一:class class Chinese: #Chinese=type(...) country='China' def __init__(self,namem,age): self.name=namem self.age=age def talk(self): print('%s is talking' %self.name) # print(Chinese) obj=Chinese('egon',18) print(obj,obj.name,obj.age) #方式二:type #定义类的三要素:类名,类的基类们,类的名称空间 class_name='Chinese' class_bases=(object,) class_body=""" country='China' def __init__(self,namem,age): self.name=namem self.age=age def talk(self): print('%s is talking' %self.name) """ class_dic={} exec(class_body,globals(),class_dic) #将字符串的命令转变为局部上下文 Execute the given source in the context of globals and locals. print(class_dic) Chinese1=type(class_name,class_bases,class_dic) # print(Chinese1) obj1=Chinese1('egon',18) print(obj1,obj1.name,obj1.age)
26 自定义元类控制类的行为
class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): if not class_name.istitle(): raise TypeError('类名的首字母必须大写') if '__doc__' not in class_dic or not class_dic['__doc__'].strip(): raise TypeError('必须有注释,且注释不能为空') super(Mymeta,self).__init__(class_name,class_bases,class_dic) class Chinese(object,metaclass=Mymeta): ''' 中文人的类 ''' country='China' def __init__(self,namem,age): self.name=namem self.age=age def talk(self): print('%s is talking' %self.name) # Chinese=Mymeta(class_name,class_bases,class_dic)
27 自定义元类控制类的实例化行为
#知识储备__call__方法 class Foo: def __call__(self, *args, **kwargs): print(self) print(args) print(kwargs) obj=Foo() obj(1,2,3,a=1,b=2,c=3) #obj.__call__(obj,1,2,3,a=1,b=2,c=3) #元类内部也应有有一个__call__方法,会在调用Foo时触发执行 #Foo(1,2,x=1) #Foo.__call__(Foo,1,2,x=1) class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): if not class_name.istitle(): raise TypeError('类名的首字母必须大写') if '__doc__' not in class_dic or not class_dic['__doc__'].strip(): raise TypeError('必须有注释,且注释不能为空') super(Mymeta,self).__init__(class_name,class_bases,class_dic) def __call__(self, *args, **kwargs): #obj=Chinese('egon',age=18) # print(self) #self=Chinese # print(args) #args=('egon',) # print(kwargs) #kwargs={'age': 18} #第一件事:先造一个空对象obj obj=object.__new__(self) #第二件事:初始化obj self.__init__(obj,*args,**kwargs) #第三件事:返回obj return obj class Chinese(object,metaclass=Mymeta): ''' 中文人的类 ''' country='China' def __init__(self,namem,age): self.name=namem self.age=age def talk(self): print('%s is talking' %self.name) obj=Chinese('egon',age=18) #Chinese.__call__(Chinese,'egon',18) print(obj.__dict__)
28 自定义元类控制类的实例化行为的应用
class MySQL: __instance=None #__instance=obj1 def __init__(self): self.host='127.0.0.1' self.port=3306 @classmethod def singleton(cls): if not cls.__instance: obj=cls() cls.__instance=obj return cls.__instance def conn(self): pass def execute(self): pass # obj1=MySQL() # obj2=MySQL() # obj3=MySQL() # # print(obj1) # print(obj2) # print(obj3) obj1=MySQL.singleton() obj2=MySQL.singleton() obj3=MySQL.singleton() print(obj1 is obj3)
class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): if not class_name.istitle(): raise TypeError('类名的首字母必须大写') if '__doc__' not in class_dic or not class_dic['__doc__'].strip(): raise TypeError('必须有注释,且注释不能为空') super(Mymeta,self).__init__(class_name,class_bases,class_dic) self.__instance=None def __call__(self, *args, **kwargs): #obj=Chinese('egon',age=18) if not self.__instance: obj=object.__new__(self) self.__init__(obj) self.__instance=obj return self.__instance class Mysql(object,metaclass=Mymeta): ''' mysql xxx ''' def __init__(self): self.host='127.0.0.1' self.port=3306 def conn(self): pass def execute(self): pass obj1=Mysql() obj2=Mysql() obj3=Mysql() print(obj1 is obj2 is obj3)
29 异常处理
#1 什么是异常:异常是错误发生的信号,一旦程序出错,并且程序没有处理这个错误,那个就会抛出异常,并且程序的运行随之终止 # # print('1') # print('2') # print('3') # int('aaaa') # print('4') # print('5') # print('6') #2 错误分为两种: #语法错误:在程序执行前就要立刻改正过来 # print('xxxx' # if 1 > 2 #逻辑错误 #ValueError # int('aaa') #NameError # name #IndexError # l=[1,2,3] # l[1000] #KeyError # d={} # d['name'] #AttributeError # class Foo: # pass # # Foo.xxx #ZeroDivisionError: # 1/0 #TypeError:int类型不可迭代 # for i in 3: # pass # import time # time.sleep(1000) #3 异常 #强调一:错误发生的条件如果是可以预知的,此时应该用if判断去预防异常 # AGE=10 # age=input('>>: ').strip() # # if age.isdigit(): # age=int(age) # if age > AGE: # print('太大了') #强调二:错误发生的条件如果是不可预知的,此时应该用异常处理机制,try...except try: f=open('a.txt','r',encoding='utf-8') print(next(f),end='') print(next(f),end='') print(next(f),end='') print(next(f),end='') print(next(f),end='') print(next(f),end='') print(next(f),end='') f.close() except StopIteration: print('出错啦') print('====>1') print('====>2') print('====>3')
30 try...except的详细用法
网络编程
选课系统作业讲解
FTP项目作业讲解
选课系统作业讲解(新)
本文来自博客园,作者:元贞,转载请注明原文链接:https://www.cnblogs.com/yuleicoder/articles/14301940.html
浙公网安备 33010602011771号