zoukankan      html  css  js  c++  java
  • python类的内部方法

    一、绑定方法与非绑定方法

    1、绑定方法

    绑定方法就是用classmethod装饰的类内部方法。

    classmethod是什么?

    • classmethod是一个装饰器,可以用来装饰类内部的方法,使该方法绑定给类来使用。

    classmethod有什么用?

    • classmethod使被装饰的方法只能由类来调用,而且该方法会将类当做第一个参数传给该方法。这种方法被称为类的绑定方法
    • 由对象来调用,会将对象当做第一个参数传给该方法。

    classmethod怎么用?

    • 和正常装饰器一样,在需要被装饰的函数上方@classmethod就可以了。

    2、非绑定方法

    非绑定方法就是用staticmethod装饰的类内部方法。

    staticmethod是什么?

    • staticmethod是一个装饰器,可以装饰给 类内部 的方法,使该方法既不绑定给对象,也不绑定给类。

    staticmethod有什么用?

    • 在类内部使用@staticmethod 修饰的方法既不绑定给对象,也不绑定给类。因此这种方法被称为非绑定方法

    staticmethod怎么用?

    • 和正常装饰器一样,在需要被装饰的函数上方@staticmethod 就可以了。

    二、property

    1、什么是property?

    property是一种python内置的装饰器,主要是给类内部的按方法使用。

    2、为什么要用property?

    使用它的目的,是将类内部的方法“def 方法名+()” 变成了 “def 方法”,

    从而使对象调用该方法时,把调用方式 "类名.方法名 + ()" 变成了 “类名.方法名”。

    3、如何使用property?

    直接在需要使用property装饰器的方法上面 @property ,和正常装饰器的使用方法一样。

    '''
    计算人体的bmi: bmi值 = 体重 / (身高 * 身高)
    
    
    '''
    class People:
        def __init__(self, name, weight, height):
            self.name = name
            self.weight = weight
            self.height = height
    
        @property
        def bmi(self):
            return self.weight / (self.height * self.height)
    
        # 了解
        @property
        def get_name(self):
            return self.name
    
        # 改
        @get_name.setter
        def set_name(self, val):
            self.name = val
    
        # 删除
        @get_name.deleter
        def del_name(self):
            del self.name
    
    
    p = People('dan', 200, 1.6)
    # print(p.bmi())  # 打印动词,看起来不合理
    # print(p.bmi)  # ---> p.bmi()
    
    # 注意: 不能对被装饰过的方法属性修改.
    # p.bmi = 18
    
    
    # 了解: 若真要通过此方法修改属性,可以通过另一种方式修改.
    print(p.get_name)
    p.set_name = 'tank'
    print(p.get_name)
    # p.del_name()
    # print(p.get_name)
    # del p.del_name
    # print(p.get_name)
    
    

    三、isinstance和issubclass

    1、isinstance

    isinstance(obj,cls):

    ​ python内置的函数,可以传入两个参数,用于判断参数1是否是参数2的一个实例。参数1一般为对象,参数2是类。

    class Foo:
        pass
    
    class Goo(Foo):
        pass
    
    
    foo_obj = Foo()
    print(isinstance(foo_obj, Foo))  # True
    print(isinstance(foo_obj, Goo))  # False
    

    2、issubclass

    issubclass(sub,super):

    ​ python内置的函数,可以传入两个函数,用于判断参数1是否是参数2 的子类。参数1和参数2都是类。

    class Foo:
        pass
    
    class Goo(Foo):
        pass
    
    print(issubclass(Goo, Foo))  # True
    
    

    四、反射

    1、什么是反射

    反射就是通过字符串来操作类或者对象的属性

    2、反射的使用

    反射有四种函数:

    1. hasattr:通过字符串,判断该字符串是否是对象或类的属性。
    2. getattr:通过字符串,获取对象或类的属性。
    3. setattr:通过字符串,设置对象或类的属性。
    4. delattr:通过字符串,删除对象或类的属性。
    class People:
        country = 'China'
    
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    
    p = People('tank', 17, 'male')
    
    # hasatter普通方式
    # print(p.__dict__)
    # print(People.__dict__)
    # hasatter
    print(hasattr(p, 'name'))  # True
    print(hasattr(People, 'country'))  # True
    
    
    # getattr普通方式
    print(p.__dict__.get('name', 'nick'))  # tank
    print(p.__dict__.get('level', 9))  # 9  # 有就取值,没有就添加值
    # getattr
    print(getattr(p, 'name', 'nick'))  # tank
    print(getattr(p, 'salary', 15000))  # 15000 # 有就取值,没有就添加值
    
    
    # setattr普通方法
    p.level = 10
    print(p.level)  # 10
    # setattr
    print(p.__dict__.get('salary'))  # None
    print(hasattr(p, 'salary'))  # False
    setattr(p, 'salary', 20000)
    print(hasattr(p, 'salary'))  # True
    print(p.salary)  # 20000
    
    
    # delattr 普通方法
    setattr(p, 'salary', 20000)
    print(hasattr(p, 'salary'))  # True
    del p.salary
    print(hasattr(p, 'salary'))  # False
    # delattr
    setattr(p, 'salary', 20000)
    print(hasattr(p, 'salary'))  # True
    delattr(p, 'salary')
    print(hasattr(p, 'salary'))  # False
    
    

    五、魔法方法

    凡是在类内部定义,以“__开头__结尾”的方法都称之为魔法方法,又称“类的内置方法”。魔法方法会在某些条件成立时触发。

    如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一切都是自动发生的。

    魔法方法 含义
    基本的魔法方法
    _new_ 在__init__执行前触发
    __init__ 构造器,当一个实例被创建的时候(调用类时)触发
    __del__ 对象被销毁前执行该方法,该方法会在最后执行。
    __str__ 定义当打印方法被调用时的行为
    __getattr__ 会在对象.属性时,“属性没有”的情况下才会触发。
    __setattr__ 会在 “对象.属性 = 属性值” 时触发。(设置属性时触发)
    __call__ 允许一个类的实例像函数一样被调用:x(a, b) 调用 x.__call__(a, b)
    class Foo(object):
    
        # 在调用之前触发,即在__init__()执行前触发,用来生成一个空的对象
        def __new__(cls, *args, **kwargs):
            print('你在生成一个空的对象')
            # print(cls)
            print(object.__new__(cls))
            return object.__new__(cls)
            # 如果没有return一个空对象,就不会触发__init__()
    
    
        # 在调用类时触发
        def __init__(self):
            print('你在调用类')
    
    
        # 在打印一个实例化对象时触发
        def __str__(self):
            print('你在打印对象')
            # 必须要有一个返回值,且改返回值必须是字符串
            # 随便打印出来什么,只是显示了而已,和对象其实没什么关系
            # 只是用来说明__str__出发了而已
            return '随便'
    
    
        # 在实例化对象即将被回收时触发。
        def __del__(self):
            print('对象即将被回收,且清空对内存的占用')
    
    
        # 在试图获取一个不存在的属性时触发
        def __getattr__(self, item):
            print('你在试图获取一个不存在的属性')
            print(item)  # item即为那个不存在的属性的属性名
            # 其实,你在用print方法来打印(对象.属性)时,
            # 虽然这个属性不存在,但是也是可以打印出结果的,
            # 印出的内容即是__getattr__()函数返回的值,
            # 没有返回内容,默认返回None。
            return f'{self}.{item} 属性不存在'  # 你在打印对象
                                              # 随便.x 属性不存在
            # return f'{item} 属性不存在'
    
    
        # 在进行设置属性(赋值)操作时触发
        def __setattr__(self, key, value):
            # key为属性的属性名,value为设置属性的属性值
            print('你在设置一个对象的属性')
            print(self.__dict__)
            print('key =',key,'value =',value)
            self.__dict__['key'] = value
            print('设置成功!')
            print(self.__dict__)
    
    
        # 在调用 对象 时触发
        def __call__(self, *args, **kwargs):
            print('你在调用一个对象!')
    
    
    
    # 即将调用类,触发__new__()
        # 你在生成一个空的对象
        # <class '__main__.Foo'>
        # 你在打印对象
        # 随便
        # 对象即将被回收,且清空对内存的占用
    
    
    # 此时在调用类,触发__init__()
    foo = Foo()  # 你在调用类
    
    
    
    # 此时在打印类,啥也没发生,就正常打印类
    print(Foo)  # <class '__main__.Foo'>
    
    
    # 此时在打印对象,触发__str__()
    print(Foo())  # 在打印对象时触发
                  # 随便
    print(foo)  # 在打印对象时触发
                # 随便
                # 如果没有__str__ 就是一个地址:
                # <__main__.Foo object at 0x0000022BA3C38188>
    
    
    # 此时在试图获取一个不存在的属性,触发__getattr__()
    foo.x  # 你在试图获取一个不存在的属性
           # x
    print(foo.x)  # 你在试图获取一个不存在的属性
                    # x
                    # x 属性不存在
    
    
    # 这里在调用一个对象,触发__call__()
    foo()  # 你在调用一个对象!
    
    
    # 这里在进行设置属性(赋值)操作,触发__setattr__()
    foo.x = 10  # 你在设置一个对象的属性
                # key = x value = 10
    
    
    # 此时实例化对象被回收时,触发__del__()
    del foo
    print('文件这个时候才运行结束')  # 对象即将被回收,且清空对内存的占用
                                 # 文件这个时候才运行结束
    
    
    '''
    你在生成一个空的对象
    你在打印对象
    随便
    对象即将被回收,且清空对内存的占用
    你在调用类
    <class '__main__.Foo'>
    你在生成一个空的对象
    你在打印对象
    随便
    对象即将被回收,且清空对内存的占用
    你在调用类
    你在打印对象
    随便
    对象即将被回收,且清空对内存的占用
    你在打印对象
    随便
    你在试图获取一个不存在的属性
    x
    你在打印对象
    你在试图获取一个不存在的属性
    x
    你在打印对象
    随便.x 属性不存在
    你在调用一个对象!
    你在设置一个对象的属性
    {}
    key = x value = 10
    设置成功!
    {'key': 10}
    对象即将被回收,且清空对内存的占用
    文件这个时候才运行结束
    '''
    
  • 相关阅读:
    LeetCode 189. Rotate Array
    LeetCode 965. Univalued Binary Tree
    LeetCode 111. Minimum Depth of Binary Tree
    LeetCode 104. Maximum Depth of Binary Tree
    Windows下MySQL的安装与配置
    LeetCode 58. Length of Last Word
    LeetCode 41. First Missing Positive
    LeetCode 283. Move Zeroes
    《蚂蚁金服11.11:支付宝和蚂蚁花呗的技术架构及实践》读后感
    删除docker下的镜像
  • 原文地址:https://www.cnblogs.com/bowendown/p/11668986.html
Copyright © 2011-2022 走看看