• python -- 面向对象进阶


    1, classmethob

    1,在类中定义一个类方法

      如果你的整个方法中都没有用到对象命名空间中的名字,且你用到了类的命名空间中的名字(普通方法和property方法除外)

    class Goods:
        __discount = 0.8 # 静态属性
        def __init__(self,price):
            self.__price = price  # 对象属性
            self.name = "apple"
        @property
        def prince(self):
            print(self)  # <__main__.Goods object at 0x036B0710>
            return self.__price * Goods.__discount
        @classmethod
        def change_discount(cls,new):  # 类方法
            cls.__discount = new
            
    obj = Goods(10)
    print(obj.prince)
    
    Goods.change_discount(0.7)
    print(Goods.__dict__)

    类方法的默认参数 : cls 值得是调用这个方法的类
    类方法的调用方式 : 通过类名调用,本质是方法

    2,staticmethod

    将一个普通的函数放到类中来就给这个函数加上一个@staticmethod装饰器
    这个函数就不需要传默认的参数:self,cls

    class Foo:
        @classmethod
        def class_methob(cls):
            pass
        @staticmethod
        def stati_methob():
            pass
    from types import MethodType,FunctionType
    obj = Foo()
    
    print(isinstance(Foo.class_methob,MethodType) # 判断是否是方法
    print(isinstance(Foo.stati_methob,FunctionType)) # 判断是否是函数
    print(obj.stati_methob)  # <function Foo.stati_methob at 0x050A5030>
    
    # isinstance 判断对象和类之间的关系
    # 判断这个对象是否是这个类、这个类的子类的对象
    
    # issubclass 判断类和类之间的关系
    # 判断一个类是否是另一个类的子类

    静态方法的调用方式 : 通过类名调用,本质还是函数

    类方法总结:

    
    

    类方法 的 特点
    # 只使用类中的资源,且这个资源可以直接用类名引用的使用,那这个方法应该被改为一个类方法

    类:
        # 静态属性         类  所有的对象都统一拥有的属性
        # 类方法           类  如果这个方法涉及到操作静态属性、类方法、静态方法                            cls 表示类
        # 静态方法         类  普通方法,不使用类中的命名空间也不使用对象的命名空间   : 一个普通的函数    没有默认参数
        # 方法             对象                                                                            self 表示对象
        # property方法     对象 

    3,isinstance 和type 区别 

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

    # print(type(123) is int)
    # print(isinstance(123,int))
    
    # class A:
    #     pass
    # class B(A):
    #     pass
    # a = A()
    # b = B()
    
    # print(type(a) is A)
    # print(type(b) is A)
    # print(type(b) is A)
    
    # print(isinstance(a,A))
    # print(isinstance(b,A))
    # print(isinstance(a,B))
    区别

    内置的 type() 函数可以用来查询变量所指的对象类型。

    >>> a, b, c, d = 20, 5.5, True, 4+3j
    >>> print(type(a), type(b), type(c), type(d))
    <class 'int'> <class 'float'> <class 'bool'> <class 'complex'>

    此外还可以用 isinstance 来判断:

    >>>a = 111
    >>> isinstance(a, int)
    True

    但是在判断继承的关系的时候,二者判断结果会有所不同:

    class A:
        pass
     
    class B(A):
        pass
     
    isinstance(A(), A)  # returns True
    type(A()) == A      # returns True
    isinstance(B(), A)    # returns True
    type(B()) == A        # returns False
    View Code

    区别就是:

    • type()不会认为子类是一种父类类型。
    • isinstance()会认为子类是一种父类类型。

    4,issubclass

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

    将一个普通的函数放到类中来就给这个函数加上一个@staticmethod装饰器
    这个函数就不需要传默认的参数:self,cls

    class A:
        pass
    class B:
        pass
    print(issubclass(A,B)) # False
    
    print(issubclass(B,A)) # False
    # 检测类与类之间的关系

    静态方法的调用方式 : 通过类名调用,本质还是函数

    5,反射

    # what 是什么
        # 反射 使用字符串数据类型的变量名来获取这个变量的值
    # a = 1
    # b = 2
    # name = 'alex'
    
    # why 为什么 三个场景
        # input
            # 用户输入的如果是a,那么就打印1,如果输入的是b就打印2,如果输入的是name,就打印alex
        # 文件
            # 从文件中读出的字符串,想转换成变量的名字
        # 网络
            # 将网络传输的字符串转换成变量的名字
    # where 在哪儿用
    # how 怎么用
    3w 1h

    1 什么是反射

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

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

    四个可以实现自省的函数

    下列方法适用于类和对象(一切皆对象,类本身也是一个对象)

    def hasattr(*args, **kwargs): # real signature unknown
        """
        Return whether the object has an attribute with the given name.
        
        This is done by calling getattr(obj, name) and catching AttributeError.
        """
        pass
    hasattr
    def getattr(object, name, default=None): # known special case of getattr
        """
        getattr(object, name[, default]) -> value
        
        Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
        When a default argument is given, it is returned when the attribute doesn't
        exist; without it, an exception is raised in that case.
        """
        pass
    getattr
    def setattr(x, y, v): # real signature unknown; restored from __doc__
        """
        Sets the named attribute on the given object to the specified value.
        
        setattr(x, 'y', v) is equivalent to ``x.y = v''
        """
        pass
    setattr
    def delattr(x, y): # real signature unknown; restored from __doc__
        """
        Deletes the named attribute from the given object.
        
        delattr(x, 'y') is equivalent to ``del x.y''
        """
        pass
    delattr
    class Foo:
        f = '类的静态变量'
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
        def say_hi(self):
            print('hi,%s'%self.name)
    
    obj=Foo('egon',73)
    
    #检测是否含有某属性
    print(hasattr(obj,'name'))
    print(hasattr(obj,'say_hi'))
    
    #获取属性
    n=getattr(obj,'name')
    print(n)
    func=getattr(obj,'say_hi')
    func()
    
    print(getattr(obj,'aaaaaaaa','不存在啊')) #报错
    
    #设置属性
    setattr(obj,'sb',True)
    setattr(obj,'show_name',lambda self:self.name+'sb')
    print(obj.__dict__)
    print(obj.show_name(obj))
    
    #删除属性
    delattr(obj,'age')
    delattr(obj,'show_name')
    delattr(obj,'show_name111')#不存在,则报错
    
    print(obj.__dict__)
    四个方法的使用演示
    class Foo(object):
     
        staticField = "old boy"
     
        def __init__(self):
            self.name = 'wupeiqi'
     
        def func(self):
            return 'func'
     
        @staticmethod
        def bar():
            return 'bar'
     
    print getattr(Foo, 'staticField')
    print getattr(Foo, 'func')
    print getattr(Foo, 'bar')
    类也是对象
    import sys
    
    
    def s1():
        print 's1'
    
    
    def s2():
        print 's2'
    
    
    this_module = sys.modules[__name__]
    
    hasattr(this_module, 's1')
    getattr(this_module, 's2')
    反射当前模块成员

    导入其他模块,利用反射查找该模块是否存在某个方法

    def test():
        print('from the test')
    
    """
    程序目录:
        module_test.py
        index.py
     
    当前文件:
        index.py
    """
    
    import module_test as obj
    
    #obj.test()
    
    print(hasattr(obj,'test'))
    
    getattr(obj,'test')()
    View Code

    __str__ 和 __repr__

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

    自定制格式化字符串__format__

    format_dict={
        'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
        'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
        'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
    }
    class School:
        def __init__(self,name,addr,type):
            self.name=name
            self.addr=addr
            self.type=type
    
        def __repr__(self):
            return 'School(%s,%s)' %(self.name,self.addr)
        def __str__(self):
            return '(%s,%s)' %(self.name,self.addr)
    
        def __format__(self, format_spec):
            # if format_spec
            if not format_spec or format_spec not in format_dict:
                format_spec='nat'
            fmt=format_dict[format_spec]
            return fmt.format(obj=self)
    
    s1=School('oldboy1','北京','私立')
    print('from repr: ',repr(s1))
    print('from str: ',str(s1))
    print(s1)
    
    '''
    str函数或者print函数--->obj.__str__()
    repr或者交互式解释器--->obj.__repr__()
    如果__str__没有被定义,那么就会使用__repr__来代替输出
    注意:这俩方法的返回值必须是字符串,否则抛出异常
    '''
    print(format(s1,'nat'))
    print(format(s1,'tna'))
    print(format(s1,'tan'))
    print(format(s1,'asfdasdffd'))
    View Code
    class B:
    
         def __str__(self):
             return 'str : class B'
    
         def __repr__(self):
             return 'repr : class B'
    
    
    b=B()
    print('%s'%b)
    print('%r'%b)
    %s和%r
  • 相关阅读:
    我的安全测试面试_自问自答,不亦乐乎
    Linux Shell 网络层监控脚本(监控包括:连接数、句柄数及根据监控反馈结果分析)
    netstat监控大量ESTABLISHED连接与Time_Wait连接问题
    详解 Spotlight on MySQL监控MySQL服务器
    详解 Spotlight on Unix 监控Linux服务器
    某听书网站系统漏洞,利用抓包拼接方式获取网站资源
    不懂得使用工具的测试不是好测试
    【好书摘要】性能优化中CPU、内存、磁盘IO、网络性能的依赖
    性能调优从哪里入手
    报文解析,从请求报文详细讲到响应码
  • 原文地址:https://www.cnblogs.com/peng104/p/9567992.html
Copyright © 2020-2023  润新知