路飞学城Python-Day19(Py_Notes)

# 先定义类
class LuffyStudent:
    school = 'luffy'

    def learn(self):
        print('学习使我快乐')

    def eat(self):
        print('吃饭使我幸福')

    def sleep(self):
        print('睡觉让我开心')


# 当定义函数的时候,不调用是不会运行函数的,函数体的代码只有在调用的时候执行,一旦执行了函数就会产生一个局部名称空间,会把函数产生的类调用出去
# 定义类,在类的定义阶段就会内部的代码就会运行
# 产生名称空间,都是一个字典的形式
# 查看类的名称空间
# print(LuffyStudent.__dict__)
# print(LuffyStudent.school)#print(LuffyStudent.__dict__['school'])
# print(LuffyStudent.learn)#print(LuffyStudent.__dict__['learn'])
#

# # 增
# LuffyStudent.county = 'China'
# print(LuffyStudent.county)

# # 删除
# del LuffyStudent.county
# print(LuffyStudent.county)

#
LuffyStudent.school = 'Luffycity1123'
print(LuffyStudent.school)
如何使用类
# g = {
#     'x':1,
#     'y':2,
# }
# l = {}
# exec('''
# global x,m
# x = 10
# m = 100
# z = 3
# ''',g, l)
# print(g.get('m'))
# print(l)
# python中一切皆对象,对象可以怎么使用?
# 1.都可以被引用,x = obj
# 2.都可以当做函数的参数传入
# 3.都可以当做函数的返回值
# 4.都可以当做容器类型的元素,l = [func, time, obj, 1]

# 类也是对象,print(type(Foo))
# class Foo:
#     pass
# obj = Foo()

# 产生类的类称之为元类,默认所有用class定义的类,他们得元类就是type
# 定义类有两种实现方式
# 1.class关键字的方式
# class Chinese:
#     country = 'China'
#     def __init__(self,name, age):
#         self.name = name
#         self.age = age
#     def talk(self):
#         print('%s is talking' % self.name)
# 2.type元类的产生
# 定义类的三要素
# 1.类的类名
# 2.类的继承,python3中默认继承object
# 3.类必须要有自己的名称空间,里面定义了自己的数据属性和函数属性
class_name = 'Chinese'
class_bases = (object, )
class_body = """
country = 'China'

def __init__(self,name,age):
    self.name = name
    self.age = age
    
def talk(self):
    print('%s is taking'%self.name)

"""
class_dic = {}
exec(class_body, globals(), class_dic)
Chinese = type(class_name, class_bases, class_dic)
print(class_dic)
元类
# class Foo:
#     pass
# obj = Foo()
# print(isinstance(obj,Foo))

# class Foo:
#     pass
# class Bar(Foo):
#     pass
#
# print(issubclass(Bar,Foo))
# class Foo:
#     def __init__(self,name):
#         self.name = name
#
#     def __getitem__(self, item):
#         # print('Get item.....')
#         # print(item)
#         return self.__dict__.get(item)
#
#     def __setitem__(self, key, value):
#         # print('Set item.....')
#         # print(key,value)
#        self.__dict__[key] = value
#     def __delitem__(self, key):
#        self.__dict__.pop(key)
#
# obj = Foo('panda')
#  #实现obj.name的实现方式,
# #  查看属性
# print(obj['name'])
# #设置赋值方式,设置属性
# obj['sex'] = 'male'
# print(obj['sex'])
# # 删除属性
# del obj['name']
# print(obj['name'])
# --------------------------------------
# class People:
#     def __init__(self, name, age):
#         self.name = name
#         self.age = age
#     def __str__(self):
#         return '<name %s age %s>' % (self.name, self.age)
# obj = People('panda',10)
# print(obj)
# 想要操作文件,就需要两个部分的资源,一个是操作系统的,一个是文件内容的
# 函数方法就是通知了操作系统,实现了打印文件的操作,在操作系统里实现了打印文件操作,但是文件的内容是放在硬盘上
# 实际上就是函数向操作系统发送了请求,告诉操作系统再去操作硬盘打开文件读取文件内容放在内存中
# 文件的操作总结---->应用程序>>操作系统>>硬盘,
# 所以利用操作系统的时候,记得在调用文件以后需要关闭,但是python的垃圾回收机制只能回收自己的变量,不能关闭操作系统级别已经打开的文件
# f.close()先回收操作系统的资源,f的回收会在程序结束的最后,利用垃圾回收机制自动回收
# ___模拟打开文件的操作,在python内部结束了以后,会自动触发__del__的操作,自动回收操作系统资源

class Open:
    def __init__(self, filename):
        print('open file...')
        self.filename = filename
    def __del__(self):
        print('Finish !')
f = Open('test.txt')
print('At the end')
内置方法
# class People:
#     county = 'China'
#     def __init__(self,name, age):
#         self.name = name
#         self.age = age
#     def talk(self):
#         print('%s is talking' %self.name)
#
# obj = People('panda', 10)
# print(obj.name)
# obj.talk()
# 用户的输入就会变成字符串,input方法就是会转换成字符串的形式
# 如果通过用户的输入,让用户通过字符串调用类的属性
# 1.hasattr(obj,str)>>判断obj下到底有没有str的参数属性,本质上就是判断字典里有没有str的属性(obj.__dict__(str))>>返回的值是布尔值(True/False)(判断有没有)
# 2.getattr(obj,str,default)>>直接显示str属性的结果,如果没有就报错,default就是直接赋值None(设置)
# 3.setattr(obj,'sex','male')>>等同于obj.sex = male设置对象的值(修改和新增)
# 4.delattr(obj, 'age')>>等同于del obj.age删除对象的值(删除)
# print(getattr(People,'county'))

class Service:
    def run(self):
        while True:
            cmd = input('>>>').strip()
            print(cmd)
            if hasattr(self,cmd):
               func = getattr(self,cmd)
               func()
    def get(self):
        print('get.....')
    def put(self):
        print('put.....')
obj = Service()
obj.run()
反射
import settings

class People:
    def __init__(self,name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex
        self.id = self.create_id()


    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():
        import hashlib
        import time
        m = hashlib.md5(str(time.time()).encode('utf-8'))
        return m.hexdigest()

# p1 = People('panda', 18, '男')
# 绑定给对象就由对象来调用,自动将对象本身当做第一个参数传入
# p1.tell_info() #tell_info(p1)
#     新需求:从配置文件里读取信息来实例化对象
# p2 = People(settings.name, settings.age, settings.sex)
# p2.tell_info()
#---------------------------------------------------#
# 绑定给类
# p = People.from_conf()
# p.tell_info()
#---------------------------------------------------#
# 非绑定方法,不与类或者对象绑定,谁都可以调用,没有自动传入值的功能
# p1 = People('panda',20,'male')
# p2 = People('pandaboy',10,'male')
# print(p1.id)
# print(p2.id)
绑定方法和非绑定方法
# # 自定义元类最好指定type,因为你只是重写一部分类的方法,本身更多的类的属性还是从type中来的
#
#
# class Mymeta(type):
#     def __init__(self,class_name, class_bases, class_dic):
#         if not class_name.istitle():
#             raise TypeError('类型错误,类名的首字母必须大写')
#         super(Mymeta,self).__init__(class_name,class_bases,class_dic)
#
#
# class Chinese(object, metaclass=Mymeta):
#     country = 'China'
#
#     def __init__(self,name, age):
#         self.name = name
#         self.age = age
#
#     def talk(self):
#         print('%s is talking' % self.name)
# # Chinese = Mymeta(class_name,class_bases,class_dic)


class Foo:
    '''
    注释
    '''
    pass
print(Foo.__dict__)
print(Foo.__doc__)
自定义元类控制类的创建
print(type([1,2]))
一切皆对象
# 方式二 super继承
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):
        super().__init__(nickname, life_value , aggresivity)
        self.weapon = weapon

    def attack(self, enemy):
        super(Garen,self).attack(enemy)  #得到了父类的对象(依赖继承,不用再传self)
        print('from Garen Class')

class Riven(Hero):
    camp = 'Noxus'

r = Riven('瑞文',100,30)
g = Garen('草丛', 100, 30,'大保健')
g.attack(r)
print(r.life_value)
在子类中重用父类的属性
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 miaomiao')

# 多态性:指的是在可以不考虑对象的类型的情况下,而直接使用对象
# 多态性就是不用考虑自己的实例类的具体类型直接执行就完事了
# 静态的多态性:使用+方法的时候无需考虑数据类型,只要是列表、数字、字符串,直接都可以相加,加就完事了


p1 = People()
d1 = Dog()
pig1 = Pig()
cat1 = Cat()

p1.talk()
d1.talk()
pig1.talk()


# 使用了同一个接口,就像学车一样,不会学开什么车,只是开车的方法就可以了
def func(animal):
    animal.talk()


func(p1)
func(pig1)
func(d1)
func(cat1)
多态与多态性
# class A:
#     __x = 1
#
#     def __init__(self, name):
#         self.__name = name
#
#     def __foo(self):
#         print('run foo')
#     def bar(self):
#         self.__foo()
#         print('form bar')
#
# a = A('panda')
# a.bar()

# class Foo:
#     def func(self):
#         print('from foo')
#
# class Bar(Foo):
#     def func(self):
#         print('from bar')
#
# b = Bar()
# b.func()


# class Foo:
#     def __func(self):
#         print('from foo')
#
#
# class Bar(Foo):
#     def __func(self):
#         print('from bar')
#
#
# b = Bar()
# b._Bar__func()
# class B:
#     __x = 1
#     def __init__(self, name):
#         self.__name = name
# #
# # B.__y = 2
# # print(B.__dict__)
# b = B('三保')
# print(b.__dict__)
# class A:
#     def foo(self):
#         print('A.foo')
#
#     def bar(self):
#         print('A.bar')
#         self.foo()
#
#
# class B(A):
#     def foo(self):
#         print('B.foo')
#
# b = B()
# b.bar()
# -------只调用自己的类,而且不能覆盖---------
# class A:
#     def __foo(self):
#         print('A.foo')
#
#     def bar(self):
#         print('A.bar')
#         self.__foo()
#
#
# class B(A):
#     def foo(self):
#         print('B.foo')
#
# b = B()
# b.bar()
封装
class Room:
    def __init__(self, name, owner, height, weight, length):
        self.name = name
        self.owner = owner
        self.__height = height
        self.__weight = weight
        self.__length = length
    def area(self):
        return self.__weight*self.__length*self.__height

r = Room('卫生间','panda',10,10,10)
print(r.area())
# 使用者的方法没有变,需求只需要变自己类的方法里的函数属性就可以了
封装与可扩展性
# 封装数据属性:明确的区分内外,只能在内部开一个接口让外部去间接的访问,可以控制用户的使用行为,可以打印为固定的格式
# 把真实的数据隐藏起来,只能访问定制的格式
# 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('panda', 19)
# p.tell_info()
# p.set_info('zombie', 1)
# 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()
封装的意义
#练习1:编写一个学生类,产生一堆学生对象
# 要求:
# 有一个计数器(属性),统计总共实例了多少个对象


class Student:
    School = 'Python大学'
    Count = 0

    def __init__(self,name, age, sex, hobby):
        self.Name = name
        self.Age = age
        self.Sex = sex
        self.Hobby = hobby
        Student.Count += 1


s1 = Student("二狗", 19, "", "篮球")
print(Student.Count)
s2 = Student("三炮", 29, "", "足球")
print(Student.Count)
s3 = Student("四妹", 17, "", "绣花")
小练习1
# 练习2:模仿LOL定义两个英雄类,
# 要求:1.英雄需要有昵称、攻击力、生命值等属性
#       2.实例化出两个英雄对象
#       3.英雄之间可以互殴,被殴打的一方掉血,血量小于0则判定死亡

class Hero:
    def __init__(self, name, attack, health, speed):
        self.Name = name
        self.Attack = attack
        self.Health = health
        self.Speed = speed

    def kill(self,hero_name):
       hero_name.Health -= self.Attack

class Zombie(Hero):
    pass

class Rabbit(Hero):
    pass

h1 = Zombie("panda", 20, 100, 20)
h2 = Rabbit("pandaboy", 30, 120, 20)

print(h1.Health)
h1.kill(h2)
print(h1.Health)
print(h2.Health)
h1.kill(h2)
print(h2.Health)
小练习2
# 为对象定制自己独有的特征
class LuffyStudent:
    school = 'luffy'
    def __init__(self, name, sex, age):
        self.Name = name
        self.Sex = sex
        self.Age = age

    def learn(self):
        print('%s 学习使我快乐' % self.Name)

    def eat(self):
        print('吃饭使我幸福')

    def sleep(self):
        print('睡觉让我开心')


stu1 = LuffyStudent('三炮', '', 28)
stu2 = LuffyStudent('大锤', '', 29)
stu3 = LuffyStudent('二狗', '', 28)
# 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(stu1.school))
# print(stu3.school,id(stu1.school))
# 对象中的共有的类的特征共用一个内存地址,类的数据属性的内存地址是所有对象共有的
# 类中的函数属性
# 类的函数属性是绑定到不同的对象里的,是不同的绑定方法,绑定给谁就只有一个方法,私有化的使用方式
# 类的内部的函数属性就是一个普通的函数内存地址
# 绑定方法的特殊之处,绑定到不同的对象是不同的绑定方法,对象调用绑定方式时,会把对象本身当做第一个参数(传给self)
# print(LuffyStudent.learn)
# LuffyStudent.learn(stu1)
# print(stu1.learn)
# stu1.learn() # stu1.learn() == LuffyStudent.learn(stu1)
# print(stu2.learn)
属性查找
import abc
class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def run(self):
        pass
    @abc.abstractmethod
    def eat(self):
        pass


class People(Animal):
    def run(self):
        print('people is walking')


class Pig(Animal):
    def run(self):
        print('pig is running')


class Dog(Animal):
    def run(self):
        print('dog is zouing')

# p1 = People()
# pig1 =Pig()
# dog1 = Dog()
#
# p1.run()
# pig1.run()
# dog1.run()
p1  = People()
抽象类的归一化
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('瑞文',100, 80)
print(g.camp)
g.attack(r)
print(r.camp)
派生
# 选课系统


class People:
    school = 'Luffycity'

    def __init__(self, name, age,sex):
        self.name = name
        self.age = age
        self.sex = sex


class Teather(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 talking' % 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(self.course_name, self.course_period, self.course_price)


class Birthday:
    def __init__(self,date):
        self.date = date


stu1 = Student('小猪',20,"", "08:30:00")
bir = Birthday("2018-09-01")
stu1.birthday = bir
print(stu1.birthday.date)
组合
# 绑定对象的方法,类去访问自己的函数属性的时候就是一个普通的函数,没有自动调用的方式
# 绑定给谁,就应该谁来调用就会把调用者当做第一个参数自动传入
# class Foo:
#     def __init__(self, name):
#         self.name = name
#
#     def tell(self):
#         print('名字是%s' %self.name)
#
# f = Foo('panda')
# print(f.tell)
# -------------------------------------------------------------------
# 绑定到类:在类的内部定义的,被装饰器classmethod修饰的方法
# class Foo:
#     def __init__(self, name):
#         self.name = name
#
#     def tell(self):
#         print('名字是%s' %self.name)
#
#     @classmethod
#     def func(cls):
#         print(cls)
#
# Foo.func()
# print(Foo)
# -------------------------------------------------------------------
# 非绑定方法:不与类或者对象绑定,没有自动传值,谁都可以用,就相当于普通函数,一点都没有绑定关系
# 就是类中定义的普通工具
class Foo:
    def __init__(self, name):
        self.name = name

    def tell(self):
        print('名字是%s' %self.name)

    @staticmethod
    def func1(x,y):
        return x+y

f = Foo('panda')
print(Foo.func1(1,2))
print(f.func1(1,3))
绑定方法和非绑定方法
#
# class Parentclass1:
#     pass
#
#
# class Parentclass2:
#     pass
#
#
# class SubClass1(Parentclass1):
#     pass
#
#
# class SubClass2(Parentclass1,Parentclass2):
#     pass
#
# print(SubClass1.__bases__)
# print(SubClass2.__bases__)
#
# 属性查找小练习


class Foo:

    def f1(self):
        print('from Foo class')

    def f2(self):
        print('from FOO f2')
        self.f1()


class Bar(Foo):
    def f1(self):
        print('from Bar.f2')



b = Bar()
b.f2()
继承
# class A:
#     pass
# class B:
#     pass
# class C:
#     pass
# class D:
#     pass
# class E:
#     pass
# class F(A,B,C,D,E):
#     pass
# print(F.mro()) #等同于F.__mro__



# # python2中的经典类:没有继承object的类以及它的子类都称为经典类
#
# class Foo:
#     pass
#
#
# class Bar(Foo):
#     pass
#
# # python2中的新式类:继承object的类以及它的子类都称为新式类
# class Foo(object):
#     pass
#
# class Bar(Foo):
#     pass

# python3中所有的类都是新式类,因为所有的类都是默认继承object的


# class Foo:
#     pass
继承的实现原理
# #单例模式:默认参数一样的情况下,就不会生成新的内存空间了,用公用的就行(实际就是一种优化的策略)
# class MySQL:
#     __instance = None
#     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 find(self):
#         pass
#
#     def update(self):
#         pass
#
#
# obj1 = MySQL.singleton()
# obj2 = MySQL.singleton()
#
# print(id(obj1))
# print(id(obj2))
# ---------------------------------------#
# 实现方式二:元类的方式
class Mymeta(type):

    def __init__(self,class_name, class_bases, class_dic):
            if not class_name.istitle():
                raise TypeError('类型错误,类名的首字母必须大写')
            super(Mymeta,self).__init__(class_name,class_bases,class_dic)
            self.__instance=None
    def __call__(self, *args, **kwargs):
        if not self.__instance:
            obj = object.__new__(self)
            self.__init__(obj)
            self.__instance = obj
        return self.__instance

class Mysql(object,metaclass=Mymeta):

    def __init__(self):
        self.host = '127.0.0.1'
        self.port = 3306

    def find(self):
        pass

    def update(self):
        pass

obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
print(id(obj1))
print(id(obj2))
print(id(obj3))
自定义元类控制类的实例化行为的应用
# class File:
#     def read(self):
#         pass
#
#     def write(self):
#         pass
#
#
# 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 writre')
#
# 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))
鸭子类型
class Chinese:
    country = 'China'
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

p1 = Chinese('panda',19,'male')
p2 = Chinese('boy',20,'Famale')
p3 = Chinese('zombie', 29, 'None')


print(p1.country)
面向对象(初级)小结
 
Win a contest, win a challenge
原文地址:https://www.cnblogs.com/pandaboy1123/p/9323884.html