第三模块 面向对象&网络编程基础 视频课程代码笔记

面向对象

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()
View Code

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__方法

#__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)
View Code 

5 属性查找

'''
在现实世界中:
    对象1:王二丫
        特征:
            学校='luffycity'
            名字='王二丫'
            性别='女'
            年龄=18
        技能:
            学习
            吃饭
            睡觉

    对象2:李三炮
        特征:
            学校='luffycity'
            名字='李三炮'
            性别='男'
            年龄=38
        技能:
            学习
            吃饭
            睡觉

    对象3:张铁蛋
        特征:
            学校='luffycity'
            名字='张铁蛋'
            性别='男'
            年龄=48
        技能:
            学习
            吃饭
            睡觉

    总结现实中路飞学院的学生类:
        相似的特征
            学校='luffycity'

        相似的技能
            学习
            吃饭
            睡觉

'''
View Code

 

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)
View Code

 

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()
View Code

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__)
View Code

 

对象之间交互

'''
练习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)
View Code

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)
View Code

 

#属性查找小练习
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)
View Code

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()
View Code

[<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
# 方式二:super() (依赖继承)

 

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()
View Code

 

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()
View Code

 

 

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)
View Code

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))


# 不一定要一个抽象类来继承
# 只要做的像鸭子,看起来像鸭子,就是鸭子
View Code

 

 

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()
View Code

 

二、 封装方法:隔离复杂度

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()
View Code

 

 

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())
View Code

 

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
'''
BMI指数

 

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
property # 将函数变为属性

 

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
setter & deleter

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)
View Code

 

 

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)
View Code

 

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__)
#item系列 像字典那样去访问

 

 

#__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__()
#__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__ 执行完后的操作

 

在对象被删除的时候,会自动先触发执行__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}
# 储备知识exec

 

# 一切皆对象,对象可以怎么用?
# 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)
#产生类的类称之为元类,默认所以用class定义的类,他们的元类是type

 

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)
View Code

 

 

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__)
#知识储备__call__方法

 

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')
View Code

 

30 try...except的详细用法

 

 

 

网络编程

选课系统作业讲解

FTP项目作业讲解

选课系统作业讲解(新)

posted @ 2021-01-20 11:31  元贞  阅读(62)  评论(0)    收藏  举报