美文网首页
面向对象进阶

面向对象进阶

作者: Snackk | 来源:发表于2018-08-31 22:10 被阅读0次
class A:
    pass
class B(A):
    pass
a = A()
b = B()
  • isinstance
  • 检测对象与类之间的关系
    print(isinstance(a,A))
    print(isinstance(b,A))
    print(isinstance(a,B))
  • issubclass
  • 检测类与类之间的关系
    print(issubclass(A,B))
    print(issubclass(B,A))

反射

好处一:实现可插拔机制,先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能
好处二:动态导入模块(基于反射当前模块成员)

  • 反射:
    使用字符串数据类型的变量名来获取这个变量的值
    就是字符串转化成变量名的一个实现
    三个场景
class BlackMedium:
    feature='Ugly'
    def __init__(self,name,addr):
        self.name=name
        self.addr=addr

    def sell_house(self):
        print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' %self.name)
    def rent_house(self):
        print('%s 黑中介租房子啦,傻逼才租呢' %self.name)

b1=BlackMedium('万成置地','回龙观天露园')

#检测是否含有某属性
print(hasattr(b1,'name'))
print(hasattr(b1,'sell_house'))

#获取属性
n=getattr(b1,'name')
print(n)
func=getattr(b1,'rent_house')
func()

# getattr(b1,'aaaaaaaa') #报错
print(getattr(b1,'aaaaaaaa','不存在啊'))

#设置属性
setattr(b1,'sb',True)
setattr(b1,'show_name',lambda self:self.name+'sb')
print(b1.__dict__)
print(b1.show_name(b1))

#删除属性
delattr(b1,'addr')
delattr(b1,'show_name')
delattr(b1,'show_name111')#不存在,则报错

print(b1.__dict__)
* input
    * 用户输入的如果是a,那么就打印1,如果输入的是b就打印2,如果输入的是name,就打印alex
* 文件
    * 从文件中读出的字符串,想转换成变量的名字
* 网络
    * 将网络传输的字符串转换成变量的名字
  • 反射类中的变量 : 静态属性,类方法,静态方法
    getattr(变量名:命名空间,字符串(必须字符串,不是就会报错):属于一个命名空间内的变量名或者函数名)

  • 判断实现
    hasattr(变量名:命名空间,字符串:属于一个命名空间内的变量名)

  • 反射对象中的变量

  • 反射模块中的变量
    import os # os就是一个模块

  • 反射本文件中的变量

import sys
print(sys.modules['__main__'])  # 本文件的命名空间
print(sys.modules[__name__])     # 反射本文件中的变量 固定的使用这个命名空间
print(sys.modules['__main__'].a)
print(getattr(sys.modules[__name__],'a'))   #a是一个变量
obj = getattr(sys.modules[__name__],'Foo')()  #反射一个类实例化一个obj
  • setattr(Foo,'School','OLDOBY') # 接受三个参数 命名空间 ‘变量名’ 变量值

  • delattr(Foo,'Country') # 接受三个参数 命名空间 ‘变量名’

不是需要程序员定义,本身就存在在类中的方法就是内置方法
内置的方法通常都长这样 : __名字__
名字 : 双下方法、 魔术方法、 内置方法
所有的双下方法,都不需要我们直接去调用,都有另外一种自动触发它的语法

  • __str__, __repr__

    • __str__
      当你打印一个对象的时候 触发str
      当你使用%s格式化的时候 触发str
      str强转数据类型的时候 触发str

    • __repr__
      repr是str的备胎
      有__str___的时候执行__str__,没有实现__str__的时候,执行 __repr__
      repr(obj)内置函数对应的结果是 __repr__的返回值
      当你使用(%r)格式化的时候 触发repr

class Foo:
    def __str__(self):      #2
        return 'Foo.str'
    def __repr__(self):     #4
        return 'Foo.repr'


class Son(Foo):
    # pass
    def __str__(self):       #1
        return 'Son.str'

    def __repr__(self):
        return 'Son.repr'    #3

s1 = Son()
print(s1)

反射总结:

反射 用字符串类型的变量名来获取变量的值
hasattr(命名空间,'变量名')
getattr(命名空间,'变量名')
    类名.静态属性  getattr(类名,'静态属性')
    类名.类方法()  getattr(类名,'类方法')()
    类名.静态方法()  getattr(类名,'静态方法')()

    对象.对象属性  getattr(对象,'对象属性')
    对象.方法()    getattr(对象,'方法')()

    模块名.方法名
    模块名.类名
    模块名.变量
    模块名.函数

    本文件反射
    import sys
    getattr(sys.modules[__name__],'所有定义在这个文件中的名字')
setattr 给命名空间的某一个名字设置一个值
delattr 删除某一个命名空间中变量对应的值
内置方法
不用调用调用这个方法就可以出发这个方法的执行
class Foo:
    def __str__(self):
        return 'abcd'
    def __repr__(self):
        return 'dcba'
obj = Foo()
__str__ :
    print(obj)
    '%s'%obj
    str(obj)
__repr__  : # 当使用会触发str方法的方式,但是Foo类内部又没有实现__str__方法的时候,都会调用__repr__
    '%r'%obj
    repr(obj)
  • __new__
    在init之前,实例化对象的第一步是new创建了一个空间
class Foo:
   def __init__(self):                 # 初始化方法
       print('执行了init')
   def __new__(cls, *args, **kwargs):  # 构造方法
       # object.__new__(cls)
       print('执行了new')
       return object.__new__(cls)
obj = Foo()

new 是小人捏出来了
init 给小人穿衣服

设计模式 常用的23种
java里来的
python
推崇设计模式 java开发
贬低设计模式 纯python开发

单例模式
一个类 只有一个实例的时候 单例模式

class Foo:
    __instance = None
    def __init__(self,name,age):                 # 初始化方法
        self.name = name
        self.age = age
        self.lst = [name]
    def __new__(cls, *args, **kwargs):  # 构造方法
        if cls.__instance is None:
            cls.__instance = object.__new__(cls)
        return cls.__instance

obj1 = Foo('alex',20)
obj2 = Foo('egon',22)
print(obj1.lst,obj2.lst)
  • __del__:析构方法 : 在删除这个类创建的对象的时候会先触发这个方法,再删除对象
class Foo:
    def __init__(self,name,age):
        self.name = name
        self.age = age
        self.file = open('file',mode = 'w')
    def write(self):
        self.file.write('sjahgkldhgl')
    def __del__(self):    # 析构方法 : 在删除这个类创建的对象的时候会先触发这个方法,再删除对象
        # 做一些清理工作,比如说关闭文件,关闭网络的链接,数据库的链接
        self.file.close()
        print('执行del了')

f = Foo('alex',20)
print(f)
  • __len__
class Foo:
    def __len__(self):
        return 1
obj = Foo()
print(len(obj))
  • __eq__
    print(alex == alex2) # alex.eq(alex2)
  • __hash__
    1.每次执行hash值都会变化
    2.在一次执行的过程中对同一个值得hash结果总是不变的
    字典为什么寻址快
    dic = {'name':'alex','age':83,'sex':'不详'}
    字典在内存中是如何存储的?
    为什么字典的key必须可hash

hash算法
1.对于相同的值在一次程序的运行中是不会变化的
2.对于不同的值在一次程序的运行中总是不同的

相关文章

  • 面向对象进阶

    decorotor - 装饰器/包装器 @property装饰器 之前我们讨论过Python中属性和方法访问权限的...

  • 面向对象进阶

    ### 动态添加属性: 1. `对象.属性名=xx`的形式。 2. 通过`setattr(对象,属性名,这个属性对...

  • 面向对象进阶

    isinstance 检测对象与类之间的关系print(isinstance(a,A))print(isinsta...

  • 面向对象进阶

    1. 抽象类和抽象方法 抽象类:使用abstract修饰的类,包含抽象方法的类必须是抽象类,但抽象类不一定包含抽象...

  • 5.1-面向对象的特征(一)继承 | 上

    原作者:无缘原博客链接:5.1-面向对象的特征(一)继承 | 上 JAVA面向对象进阶 本章重点针对面向对象的三大...

  • [JAVA]面向对象的三大特性

    学习Java的进阶过程,是理解面向对象的思想,掌握面向对象的基本原则以及Java面向对象基本实现原理,熟练使用封装...

  • JS基础到高级

    JS高级-进阶目录======================基础Web API面向对象编程继承函数进阶正则表达式...

  • 17、python面向对象进阶

    面向对象进阶 isinstance和issubclass isinstance(obj,cls)检查是否obj是否...

  • 面向对象编程进阶

    前言 我们在了解面向对象的入门知识,知道如何定义一个类和对象的时候,我们应该向它更深的知识进行拓展。 @prope...

  • 面向对象编程进阶

    可见性和属性装饰器在很多面向对象编程语言中,对象的属性通常会被设置为私有(private)或受保护(protect...

网友评论

      本文标题:面向对象进阶

      本文链接:https://www.haomeiwen.com/subject/minewftx.html