zoukankan      html  css  js  c++  java
  • python面向对象进阶

    前言

    上节大话python面向对象对面向对象有了一些了解,这次就不用大话风格了          (ps:真心不好扯啊)

    isinstance与issubclass

    isinstance(obj,cls)检查是否obj是否是类 cls 的对象

    class Foo(object):
         pass
      
    obj = Foo()
      
    isinstance(obj, Foo)

    issubclass(sub, super)检查sub类是否是 super 类的派生类 

    class Foo(object):
        pass
     
    class Bar(Foo):
        pass
     
    issubclass(Bar, Foo)

    python 反射

    1 什么是反射

    反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

    2 python面向对象中的反射:

    通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

    反射即想到4个内置函数分别为:getattr、hasattr、setattr、delattr  获取成员、检查成员、设置成员、删除成员

    下面逐一介绍

     1 class Foo:
     2     def __init__(self):
     3 
     4         self.name='python反射'
     5 
     6     def func(self):
     7 
     8         print("这是一个func方法")
     9 
    10 # getattr获取成员
    11 obj=Foo()
    12 
    13 ret=getattr(obj,'name')
    14 
    15 print(ret)#输出   python反射
    16 
    17 # hasattr检查成员
    18 
    19 ret=hasattr(obj,'name')
    20 print(ret) #输出 True
    21 
    22 # setattr设置成员
    23 
    24 setattr(obj,'name','new python反射')
    25 
    26 print(obj.name)#输出  new python反射
    27 
    28 # delattr删除成员
    29 
    30 delattr(obj,'name')
    31 
    32 print(obj.name)#报错  AttributeError: 'Foo' object has no attribute 'name'

    __str__与__repr__

    改变对象的字符串显示__str__,__repr__

    __repr__和__str__这两个方法都是用于显示的,__str__是面向用户的,而__repr__面向程序员。

    • 打印操作会首先尝试__str__和str内置函数(print运行的内部等价形式),它通常应该返回一个友好的显示。

    • __repr__用于所有其他的环境中:用于交互模式下提示回应以及repr函数,如果没有使用__str__,会使用print和str。它通常应该返回一个编码字符串,可以用来重新创建对象,或者给开发者详细的显示。

    区别:

    class Foo:
        def __init__(self):
    
            self.name='python反射'
    
        def __repr__(self):
            return "这是一个repr方法"
        def __str__(self):
            return "这是一个str方法"
    
    print(Foo())

    class Foo:
        def __init__(self):
    
            self.name='python反射'
    
        def __repr__(self):
            return "这是一个repr方法"
        # def __str__(self):
        #     return "这是一个str方法"
    
    print(Foo())

    也就是说,在__str__不存在的情况下,print会直接使用__repr__返回的值。当我们想所有环境下都统一显示的话,可以重构__repr__方法;当我们想在不同环境下支持不同的显示,例如终端用户显示使用__str__,而程序员在开发期间则使用底层的__repr__来显示,实际上__str__只是覆盖了__repr__以得到更友好的用户显示。

    以下几种情况会触发__repr__与__str__的调用 ,%s格式化字符串,print输出,str()

    __del__

    析构方法,当对象在内存中被释放时,自动触发执行。

    注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

    class Foo:
        def __init__(self):
    
            self.name='python反射'
    
        def __del__(self):
            print("我是析构函数")
    
    Foo()

    __getitem__ __setitem__ __delitem__   三基佬

    class Foo:
        def __init__(self,name):
            self.name=name
    
        def __getitem__(self, item):
            print(self.__dict__[item])
    
        def __setitem__(self, key, value):
            self.__dict__[key]=value
        def __delitem__(self, key):
            print('del obj[key]时,我执行')
            self.__dict__.pop(key)
        def __delattr__(self, item):
            print('del obj.key时,我执行')
            self.__dict__.pop(item)
    
    f1=Foo('sb')
    f1['age']=18
    f1['age1']=2
    del f1.age1
    del f1['age']
    f1['name']='item系列'
    print(f1.__dict__)

     __new__

    class A:
        def __init__(self):
            self.x = 1
            print('in init function')
        def __new__(cls, *args, **kwargs):
            print('in new function')
            return object.__new__(A, *args, **kwargs)
    
    a = A()
    print(a.x)

    单例模式

    class Singleton:
        def __new__(cls, *args, **kw):
            if not hasattr(cls, '_instance'):
                cls._instance = object.__new__(cls)
            return cls._instance
    
    one = Singleton()
    two = Singleton()
    
    two.a = 3
    print(one.a)
    # 3
    # one和two完全相同,可以用id(), ==, is检测
    print(id(one))
    # 29097904
    print(id(two))
    # 29097904
    print(one == two)
    # True
    print(one is two)
    
    单例模式

    __call__

    对象后面加括号,触发执行。

    class Foo:
        def __init__(self):
            self.name='__call__方法'
    
    
        def __call__(self, *args, **kwargs):
    
            print("调用call方法")
    
    
    Foo()()#输出   调用call方法

    __len__

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
        def __len__(self):
            return len(self.__dict__)
    a = A()
    print(len(a))

    __eq__ 与 __hash__

    遇到了一次关于这哥俩的面试题,就把他放一块吧

    题目是这样的:一百个对象去重,如果name与gender相同就代表两对象相同(类似于java的重写equal)

    class Person:
        def __init__(self,name,age,gender):
            self.name = name
            self.age = age
            self.gender = gender
    
        def __hash__(self):
            return hash(self.name+self.gender)
    
        def __eq__(self, other):
            if self.name == other.name and self.gender == other.gender:return True
    
        def __str__(self):
            return self.name
    
    p_lst=[Person('python',20,''),Person('python',18,''),Person('linux',20,'')]
    
    ret=set(p_lst)#   多方便,重写这仨哥们就完事了
    for i in ret:
        print(i)
  • 相关阅读:
    Do You See Me? Ethical Considerations of the Homeless
    ELDER HOMELESSNESS WHY IS THIS AN ISSUE?
    Endoflife support is lacking for homeless people
    html内联框架
    html字体
    html块 div span
    html列表
    html表格
    SQL Server管理员专用连接的使用   作为一名DBA,经常会处理一些比较棘手的服务无响应问题,鉴于事态的严重性,多数DBA可能直接用“重启”大法,以便尽快的恢复生产环境的正常运转,但是多数情况
    如何配置最大工作线程数 (SQL Server Management Studio)
  • 原文地址:https://www.cnblogs.com/qflyue/p/8330601.html
Copyright © 2011-2022 走看看