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}
    对象即将被回收,且清空对内存的占用
    文件这个时候才运行结束
    '''
    
  • 相关阅读:
    单链表的相关操作
    R学习-- 数组和矩阵
    UIButton 设置圆角 边框颜色 点击回调方法
    【独立开发人员er Cocos2d-x实战 007】使用Cocos2dx UserDefault.xml
    聊一聊多源最短路径问题(仅仅有5行代码哦)
    Android cookies正确的更新方式
    Android IntentService的使用和源代码分析
    Android应用之——最新版本号SDK V2.4实现QQ第三方登录
    嵌套路由
    我自己用
  • 原文地址:https://www.cnblogs.com/bowendown/p/11668986.html
Copyright © 2011-2022 走看看