zoukankan      html  css  js  c++  java
  • Python 属性方法、类方法、静态方法、 特殊属性__doc__ (内建属性)

    总结:和类的关联性讲:属性方法>类方法>静态方法

    属性方法@property:仅仅是调用方式不用+括号。

    类方法@classmethod:访问不了累的属性变量,只可以访问类变量。

    静态方法@staticmethod:仅仅是通过类名来调用这个函数而已,和类本身已经没有功能关系了,严格讲已经不是类的方法而是一个通过类名调用的函数而已(无法访问实例化的类的任何属性过着其他方法)。

    在类中的方法加如下装饰器

    属性方法:@property将方法变为类的一个静态属性,调用的时候无需加括号。对外隐藏实现细节,对于用户来讲,感觉就是在查一个写死的

    class Flight(object):
        def __init__(self,name):
            self.name = name
            # flight_status
        def check_flight(self):
            print('checking flight %s: status'% self.name)
            status = 3
            return status
        @property #为类的一个静态属性,调用的时候无需加括号。对外隐藏实现细节,对于用户来讲,感觉就是在查一个写死的静态属性
        def flight_status(self):
            status  = self.check_flight
            if status == 0:
                print('flight got canceled...')
            elif status == 1:
                print('flight is arrived...')
            elif status == 2:
                print('flight has departured already...')
            else:
                print('cannot confirm the flight status ....please check later')
        @flight_status.setter #对属性方法里面的参数进行修改
        def flight_status(self,status):
            self.check_flight = status
            status_dict = {
                0:'canceled',
                1:'arrived',
                2:'departured'
            }
            print('33[31;1mhas changed flight:%s status to:%s33[0m'%(self.name,status_dict[status]))
        @flight_status.deleter #加上删除装饰器,这个静态方法就可以被删除
        def flight_status(self):
            print('status Func got removed')
    
    f1 = Flight("川航3U8633")
    f1.flight_status  #不用加括号
    f1.flight_status = 1
    f1.flight_status
    del f1.flight_status
    f1.flight_status
    更改航班状态(属性方法应用)

    静态方法:@staticmethod

    只是名义上归类管理,实际上在静态方法里访问不了类或者实例的任何属性

    class Dog(object):
    
        def __init__(self,name):
            self.name = name
        def talk(self):
            print('%s talking: 旺旺旺!'% self.name)
        @staticmethod
        def eat(self,food):
            print('%s eating %s'%(self.name,food))
    
    d1 = Dog('ChenRonghua')
    d1.eat('包子')
    View Code
    Traceback (most recent call last):
      File "C:/Users/Administrator/Desktop/Python3_study/day6/静态方法_类方法.py", line 15, in <module>
        d1.eat('包子')
    TypeError: eat() missing 1 required positional argument: 'food'

    类方法:@classmethod

    只能访问类变量,不能访问实例变量

    class Dog(object):
        name = '类方法调用测试用类变量'
        def __init__(self,name):
            self.name = name
        def talk(self):
            print('%s talking: 旺旺旺!'% self.name)
        # @staticmethod
        @classmethod
        def eat(self,food):
            print('%s eating %s'%(self.name,food))
    d1 = Dog('ChenRonghua')
    d1.eat('包子')
    View Code
    类方法调用测试用类变量 eating 包子
    
    Process finished with exit code 0

    类的内置方法__doc__

    class Dog(object)
    class Dog(object):
        '''描述一个狗的样子'''
        pass
    print(Dog.__doc__)

    输出:描述一个狗的样子
    

     类的内置方法__module__;__class__

    class C(object):
        pass
    lib/test.py
    from lib import test
    obj = test.C()
    print(obj.__module__)
    print(obj.__class__)
    测试.py
    输出结果
    lib.test
    <class 'lib.test.C'>
    

     

    3. __init__ 构造方法,通过类创建对象时,自动触发执行。

    4.__del__

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

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

      

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

    注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

     

    class Dog(object):
        name = '类方法调用测试用类变量'
        def __init__(self,name):
            self.name = name
        # def talk(self):
        #     print('%s talking: 旺旺旺!'% self.name)
        # # @staticmethod
        # @classmethod
        # def eat(self,food):
        #     print('%s eating %s'%(self.name,food))
        def __call__(self, *args, **kwargs):
            print("我了个__call__")
    d1 = Dog('ChenRonghua')
    d1()
    
    输出:我了个__call__
    View Code

    6.__dict__ 查看类或对象中的所有成员   

    class Dog(object):
        name = '类方法调用测试用类变量'
        def __init__(self,name):
            self.name = name
    
        def __call__(self, *args, **kwargs):
            print("我了个__call__")
    d1 = Dog('ChenRonghua')
    print(d1.__dict__)
    print(Dog.__dict__)
    View Code
    输出:
    {'name': 'ChenRonghua'}
    {'__module__': '__main__', 'name': '类方法调用测试用类变量', '__init__': <function Dog.__init__ at 0x0000002A9CE32AE8>, '__call__': <function Dog.__call__ at 0x0000002A9CE32B70>, '__dict__': <attribute '__dict__' of 'Dog' objects>, '__weakref__': <attribute '__weakref__' of 'Dog' objects>, '__doc__': None}
    

    7.__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

    class Dog(object):
        def __str__(self):
            return "我是类中__str__方法 return的字符串"
        def __init__(self,name):
            self.name = name
    
    d1 = Dog('ChenRonghua')
    
    print(d1)
    输出:我是类中__str__方法 return的字符串

    8.__getitem__、__setitem__、__delitem__

    用于索引操作,如过一个类的属性中有类似字典格式的数据。以上内置方法 分别表示获取、设置、删除 该类实例化的实例属性中的数据

    class Foo(object):
        def __init__(self):
            self.data = {}
        def __setitem__(self, key, value):
            self.data[key] = value
        def __getitem__(self, key):
            return self.data.get(key) #字典的get(key)方法,不会因为没有key报错
        def __delitem__(self, key):
            print('33[32;1m你让我删,我就删啊33[0m')
            del self.data[key]
    obj = Foo()
    obj['name'] = 'zhangmingda' #自动触发执行__setitem__(self, key, value):
    obj['age'] = 23
    print(obj.data)
    value = obj['age'] #自动触发执行__getitem__(self, key):
    print(value)
    del obj['age'] #自动触发执行__delitem__(self, key):
    View Code
    {'name': 'zhangmingda', 'age': 23}
    23
    你让我删,我就删啊
    
    Process finished with exit code 0
    输出结果

    类的起源:type

    def func(self):
        print('我是类的方法,不是函数')
    def __init__(self,name,age):
        self.name = name
        self.age = age
    Foo = type('Foo',(object,),{'func':func,'__init__':__init__})#定义一个类的原始写法'func'和'__init__'为类的方法名
    f1 = Foo('zhangmingda',23)
    f1.func()
    print(f1.name,f1.age)
    我是类的方法,不是函数
    zhangmingda 23

    自定义一个原类 :__metaclass__

    __metaclass__:作用-->定义一个类创建的过程

    class MyType(type):
        def __init__(self,*args,**kwargs):
            print("Mytype __init__",*args,**kwargs)
    
        def __call__(self, *args, **kwargs):
            print("Mytype __call__", *args, **kwargs)
            obj = self.__new__(self)
            print("obj ",obj,*args, **kwargs)
            print(self)
            self.__init__(obj,*args, **kwargs)
            return obj
    
        def __new__(cls, *args, **kwargs):
            print("Mytype __new__",*args,**kwargs)
            return type.__new__(cls, *args, **kwargs)
    
    print('here...')
    class Foo(object,metaclass=MyType):
        # __metaclass__ = MyType
        def __init__(self,name):
            self.name = name
            print("Foo __init__")
    
        def __new__(cls, *args, **kwargs): #new的作用,将类实例化。没有new,__init__(self)构造函数不会执行
            print("Foo __new__",cls, *args, **kwargs)
            return object.__new__(cls) #继承原类
    
    f = Foo("Alex")
    print("f",f)
    print("fname",f.name)
    __metaclass__

    内建属性__init__ ; __getattribute__

    子类没有实现__init__方法时,默认自动调用父类的。 如定义__init__方法时,需自己手动调用父类的 __init__方法

    常用专有属性说明触发方式
    __init__ 构造初始化函数 创建实例后,赋值时使用,在__new__
    __new__ 生成实例所需属性 创建实例时
    __class__ 实例所在的类 实例.__class__
    __str__ 实例字符串表示,可读性 print(类实例),如没实现,使用repr结果
    __repr__ 实例字符串表示,准确性 类实例 回车 或者 print(repr(类实例))
    __del__ 析构 del删除实例
    __dict__ 实例自定义属性 vars(实例.__dict__)
    __doc__ 类文档,子类不继承 help(类或实例)
    __getattribute__ 属性访问拦截器 访问实例属性时
    __bases__ 类的所有父类构成元素 类名.__bases__

    __getattribute__例子:

    class Itcast(object):
        def __init__(self,subject1):
            self.subject1 = subject1
            self.subject2 = 'cpp'
    
        #属性访问时拦截器,打log
        def __getattribute__(self,obj):
            if obj == 'subject1':
                print('log subject1')
                return 'redirect python'
            else:   #测试时注释掉这2行,将找不到subject2
                return object.__getattribute__(self,obj)
    
        def show(self):
            print('this is Itcast')
    
    s = Itcast("python")
    print(s.subject1)
    print(s.subject2)
    #运行结果:
    
    
    log subject1
    redirect python
    cpp

    __getattribute__的坑

        class Person(object):
            def __getattribute__(self,obj):
                print("---test---")
                if obj.startswith("a"):
                    return "hahha"
                else:
                    return self.test
    
    
            def test(self):
                print("heihei")
    
    
        t.Person()
    
        t.a #返回hahha
    
        t.b #会让程序死掉
            #原因是:当t.b执行时,会调用Person类中定义的__getattribute__方法,但是在这个方法的执行过程中
            #if条件不满足,所以 程序执行else里面的代码,即return self.test  问题就在这,因为return 需要把
            #self.test的值返回,那么首先要获取self.test的值,因为self此时就是t这个对象,所以self.test就是
            #t.test 此时要获取t这个对象的test属性,那么就会跳转到__getattribute__方法去执行,即此时产
            #生了递归调用,由于这个递归过程中 没有判断什么时候推出,所以这个程序会永无休止的运行下去,又因为
            #每次调用函数,就需要保存一些数据,那么随着调用的次数越来越多,最终内存吃光,所以程序 崩溃
            #
            # 注意:以后不要在__getattribute__方法中调用self.xxxx
  • 相关阅读:
    将变量名变为字符串
    sqlte3 的约束
    sqlte3 的基本使用4
    sqlite 的基本使用3
    sqlite 的基本使用2
    sqlite 的基本使用1
    TCP和UDP的区别(转)
    Mac 如何优雅的使用Microsoft office
    RGB和HSV颜色空间
    腾讯云视频开发相关参考
  • 原文地址:https://www.cnblogs.com/zhangmingda/p/9162425.html
Copyright © 2011-2022 走看看