复习

---恢复内容开始---

# import os
# os.rename("复习.py","02复习.py")


# 面向对象:
    #理解:写代码时什么时候用面向对象  。处理比较复杂的角色之间关系的时候(代码量多,功能多的时候)# 可以解决角色之间的功能,去掉重复代码
    # 代码清晰度更高,无论开发者还是使用者都能理解各种角色的方法和属性
    # python里面一切皆对象
        #基础数据类型都是对象。都有属于它明确的方法和属性

    # 类型和类的关系
    #     类型和类是一个东西
    #     type(obj)  obj是一个对象,那么他的type就是他的类型
    # 创建一个类
        # 类名()实例化
        # __new__()创造一个对象的空间,一些简单的初始化
    # 创建一个对象
        # class 类名 语法级别的python解释器读到这句话时
        # type是所有类的元类,object是所有类的基类
        # 类也是被创建出来的,type创建类
        # class A(metaclass = type)
        # type(cls) = type
        # 那么type就是这个类的元类
    # type(obj)的结果就是这个对象所属的类
#     # type(cls)的结果就是创建这个类的元类,大多数情况下都是type ,除非指定元类  class A(metaclass = 指定元类名)
# class A:
#     pass
# a = A()
print(type(a))  # <class '__main__.A'>
# print(type(A))#  <class 'type'>

面试题

class Lei:
    ROLE = "china"
    print(ROLE)  # 这里会直接打印
class Lei:
    ROLE = "qqq"
    print(ROLE)  # 这里会直接打印
    print(Person.ROLE)  # NameError: name 'Person' is not defined
    # 原因。这里执行这个类时先从上到下先执行一便,执行完后把Person指向这个空间

    def func(self):pass
# 类是什么时候被加载的以及类是什么时候生效的
# 对象
# 类创造对象的过程就是实例化过程 构造new,初始化init
#可以通过指针找到类空间和的内容
# 对象本身内部也存储了一些只属于对象的属性
# 组合
#什么有什么的关系
# 一个类本身的对象作为另一个对象的属性

继承
单继承和多继承
# 继承
#     单继承和多继承
        # 单继承
            # 子类的对象调用某个方法
            # 子类有: 调用子类的
            # 子类有但调用父类的:
                # super  #super().方法名(除开self所有的参数)
                # 父类名  # 父类名.方法名(self....)
            # 在任何类中调用的方法,都要自行辨别这个self到底是谁的对象

# class Foo:
#     def __init__(self):
#         self.func()
#
#     def func(self):
#         print("Foo.func")
#
# class Son(Foo):
#     def func(self):
#         print("Son.func")
# s = Son()  # Son.func
        # 多继承
            # 新式类 广度优先 - C3算法
            # mro方法查看继承顺序
            # py3默认都是新式类,py2默认都是经典类

            # 经典类:深度优先
                # 不继承object
                # 没有mro
class A:
    def func(self):
        print("A")

class B(A):
    def func(self):
        super().func()
        print("B")

class C(A):
    def func(self):
        super().func()
        print("C")

class D(B,C):
    def func(self):
        super().func()
        print("D")

# d = D()
# d.func()
# A
# C
# B
# D
# b = B()
# # b.func()
# # A
# # B
# 根据mro c3算法

子类和父类

#     子类和父类
    #什么是什么的关系
    # 经典类和新式类

    # 抽象类和接口类
    #    不能被实例化
        #规范子类当中必须实现某个方法
        # 有原生的实现抽象类的方法,但没有原生实现接口类的方法
        # java中 只支持单继承。于是就有了interface接口的概念,接口支持多继承。j
        # python中不严格区分接口类和抽象类

多态

# 多态
    # 一种类型的多种形态  多个子类去继承父类,每一个子类都是父类的一种形态
    
class Animal:pass
class Tiger(Animal):pass
class Frog(Animal):pass
    # 处处都是多态
    #鸭子类型
    # 规范全凭自觉

封装

# 封装 私有的
    # 广义的封装  把方法和属性都封装在一个类型,定义一个规范来描述一类事物
    # 狭义的封装  私有化  只能在类的内部访问
    # __静态变量  私有方法 私有的对象属性 私有的类方法 私有的静态方法
    # 在内存中存储的 _类名__名字 
    # 为什么在类中的内部可以使用__访问:在类的内部访问,程序知道自己在哪个类里面
    # 在子类中可以访问父类的私有变量嘛.不行
    # 私有,不能在类的外部,也不能被继承

property

# property  帮助你将类中的方法伪装成属性
    # 调用方法的时候不需要主动加括号
    # 让程序的逻辑性更加合理
    # @方法名.setter  装饰器.修改被property装饰的属性的时候就会调用被这个装饰器装饰的方法.除了self 之外还有一个参数被修改的值
    # @方法名.deleter 装饰器,当要删除被property装饰的属性的时候会调用这个被这个装饰器装饰的方法

class A:
    @property
    def name(self):  # 这个方法本身就是一个属性,这个变量会随着这个类/对象的一些基础变量的变化而变化
        return "abc"
    @name.deleter
    # def name(self):
    #     del A.name
    def name(self):
        print("dudud")

a = A()
print(a.name)
del a.name  # 执行这句话的时候会执行  @name.deleter    def name(self):    del A.name  这段代码.如果修改为其他操作,他仍然会执行.

# classmethod

#classmethod 类方法的装饰器,内置函数
# 使用类名调用,默认传类名为第一个参数
# 不用对象命名空间中的内容,而用到了类命名空间中的变量(静态属性),或者类方法和静态方法..
class Goods:
    __discount = 0.8
    def __init__(self,price):
        self.__price = price

    @property
    def price(self):
        return self.__price * self.__discount

    # def change_diccount(self,num):
    #     Goods.__discount = num   # 因为不需要使用任何实例上的操做,所以如果只要类名调用的更好
    @classmethod
    def change_discount(cls,num):
        cls.__discount = num

    # 商场的程序
apple = Goods(10)
banana = Goods(15)
print(apple.price)
# apple.change_diccount(1.0)
Goods.change_discount(1.0)
print(apple.price)
print(banana.price)

staticmethod

# staticmethod  静态方法的装饰器 内置函数
# 如果一个类里面的方法,既不需要用到self中的资源,也不用到cls的资源
# 相当于一个普通函数
# 但是由于一些原因,把这个方法放入类中,这时候就得把这个方法变成静态方法

列表操作时 insert(位置,参数)  和pop(n) 会浪费大量时间 pop()和append()可以使用

 

反射

# 反射 从某个指定的命名空间中,用字符数据类型的变量名来获取变量的值
# 类名反射 静态属性 类方法 静态方法
# 对象反射 对象属性 方法
# 模块反射  模块中的方法
# 自己模块中


# import sys
# myfile = sys.modules['__main__']
# getattr(myfile,'变量名')

# hasattr /getattr / setattr / delattr
# 参数
    # (明明空间,"变量名")
    # setattr(命名空间,"变量名","新的值")
# 变量名
    # 只能拿到字符串的版本
    # 从文件里拿
    # 交互拿   :input/网络传输

进阶

# 进阶
    # 内置方法 /魔术方法/双下方法
    # __名字__  不是被直接掉用的
    # 内置函数/面向对象中特殊方法/python提供的语法糖
    # __str__,str(obj)必须在对象中实现了obj方法,并且这个方法返回的数据类型必须是str类型 __call__,(用类写转世器的时候必须使用) 
# __new__,(在实例化的过程中,最先执行的方法,用来创建方法) __len__,要求这个方法的返回值必须返回int类型,len(obj) 要求obj必须实现了__len__方法__init__(实例化的工程中在new执行后自动执行)
# x = 5
# y = 6
# print(x.__add__(y))

class Mytype:
    def __init__(self,a):
        self.a = a

    def __add__(self, other): # 这里的other也是一个对象
        return self.a.count('*') + other.a.count('*')

obj1 = Mytype("afa***DGFD**")
obj2 = Mytype("dasFASF**HEFsfe**BVF")
print(obj1.__add__(obj2))
print(obj2 + obj1)  # 语法糖  __add__ 对应+

# __repr__

# a = "123"
# print(a)
# print(repr(a))
class A:
def __init__(self,name):
self.name = name

def __repr__(self):
return self.name

def __str__(self):
return "{}**".format(self.name)


class B(A):
def __init__(self,name):
self.name = name
def __repr__(self):
return "B"

a = A("abc")
print(a) # 在没有__str__的情况下,str print %s # 都根据repr返回, 如果有则返回__str__ str print %s 都会根据str返回
print(str(a)) # 调用类里面的__str__
print(repr(a)) # 调用而是__repr__
print("%s | %r" %(a,a))

# __repr__对应的是repr(obj) 和%r ,在没有__str__的情况下会 对应 str print %s

b = B("acnd")
print(b)
print(str(b)) # 在本类中没有找到__str__, 于是就找父类的str,值到找遍除了object外的所有父类都没有找到__str_,那么就找本类的__repr__

c = "cccc"
print("----%s-----" % repr(c))
print("----%r------" % str(c))
posted @ 2019-03-27 09:22  杨fj  阅读(110)  评论(0编辑  收藏  举报