美文网首页
Python高级第四天

Python高级第四天

作者: code与有荣焉 | 来源:发表于2019-12-01 16:55 被阅读0次

    对象属性管理

    Python下一切皆对象,每个对象都有多个属性(attribute),Python对属性有一套统一的管理方案。__dict__是用来存储对象属性的一个字典,其键为属性名,值为属性的值。

    一、__dict__

    Spring.dict['season']就是访问类属性,同时通过.号也可以访问该类属性

    class Person(object):                      
        name = 'python'                        
        age = 18                               
    
        def __init__(self):                    
            self.sex = 'boy'                   
            self.like = 'papapa'               
    
        @staticmethod                          
        def stat_func():                       
            print 'this is stat_func'          
    
        @classmethod                           
        def class_func(cls):                   
            print 'class_func'                 
    
    
    person = Person()                          
    print 'Person.__dict__: ', Person.__dict__ 
    print 'person.__dict__: ', person.__dict__
    

    运行结果:

    Person.__dict__:  {'__module__': '__main__', 'name': 'python', '__init__': <function __init__ at 0x000000000385B518>, 'class_func': <classmethod object at 0x0000000003847F78>, '__dict__': <attribute '__dict__' of 'Person' objects>, 'age': 18, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'stat_func': <staticmethod object at 0x00000000037CFAF8>}
    person.__dict__:  {'like': 'papapa', 'sex': 'boy'}
    

    由此可见, 类的普通方法、类方法、静态方法、全局变量以及一些内置的属性都是放在类对象dict里

    实例对象中存储了一些self.xxx的一些东西

    在类的继承中,子类有自己的dict, 父类也有自己的dict,子类的全局变量和方法放在子类的dict中,父类的放在父类dict中。

    class Person(object):                          
        name = 'python'                            
        age = 18                                   
    
        def __init__(self):                        
            self.sex = 'boy'                       
            self.like = 'papapa'                   
    
        @staticmethod                              
        def stat_func():                           
            print 'this is stat_func'              
    
        @classmethod                               
        def class_func(cls):                       
            print 'class_func'                     
    
    
    class Hero(Person):                            
        name = 'super man'                         
        age = 1000                                 
    
        def __init__(self):                        
            super(Hero, self).__init__()           
            self.is_good = 'yes'                   
            self.power = 'fly'                     
    
    
    person = Person()                              
    print 'Person.__dict__: ', Person.__dict__     
    print 'person.__dict__: ', person.__dict__     
    
    hero = Hero()                                  
    print 'Hero.__dict__: ', Hero.__dict__         
    print 'hero.__dict__: ', hero.__dict__
    

    运行结果:

    Person.__dict__:  {'__module__': '__main__', 'name': 'python', '__init__': <function __init__ at 0x000000000374B518>, 'class_func': <classmethod object at 0x0000000003750048>, '__dict__': <attribute '__dict__' of 'Person' objects>, 'age': 18, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'stat_func': <staticmethod object at 0x0000000003737FD8>}
    person.__dict__:  {'like': 'papapa', 'sex': 'boy'}
    Hero.__dict__:  {'age': 1000, '__doc__': None, '__module__': '__main__', '__init__': <function __init__ at 0x000000000374B668>, 'name': 'super man'}
    hero.__dict__:  {'is_good': 'yes', 'like': 'papapa', 'power': 'fly', 'sex': 'boy'}
    

    从运行结果可以看出,类对象的dict虽然没有继承父类的,但是实例对象继承了父类的实例属性

    二、_slots_

    现在我们终于明白了,动态语言与静态语言的不同

    • 动态语言:可以在运行的过程中,修改代码

    • 静态语言:编译时已经确定好代码,运行过程中不能修改

    如果我们想要限制实例的属性怎么办?比如,只允许对Person实例添加name和age属性。

    为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:

    class Person:
        __slots__ = ("name", "age")
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
    p = Person("老王",20)
    p.score = 100
    

    输出

    Traceback (most recent call last):
      File "C:/Users/Administrator/PycharmProjects/test/app.py", line 8, in <module>
        p.score = 100
    AttributeError: 'Person' object has no attribute 'score'
    

    注意:
    使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的
    当你定义__slots__后,Python就会为实例使用一种更加紧凑的内部表示。(__dict____doc__等属性都会不见,节省内存)

    实例通过一个很小的固定大小的数组来构建,而不是为每个实例定义一个字典。

    所以__slots__是创建大量对象时节省内存的方法。

    __slots__的副作用是作为一个封装工具来防止用户给实例增加新的属性。

    尽管使用__slots__可以达到这样的目的,但是这个并不是它的初衷。

    三、属性管理

    1. hasattr()函数

    hasattr()函数用于判断对象是否包含对应的属性

    语法:
    
      hasattr(object,name)
    
    参数:
    
      object--对象
    
      name--字符串,属性名
    
    返回值:
    
      如果对象有该属性返回True,否则返回False
    

    示例:

    class People:
        country='China'
        def __init__(self,name):
            self.name=name
    
        def people_info(self):
            print('%s is xxx' %(self.name))
    
    obj=People('aaa')
    
    print(hasattr(People,'country'))
    #返回值:True
    print('country' in People.__dict__)
    #返回值:True
    print(hasattr(obj,'people_info'))
    #返回值:True
    print(People.__dict__)
    ##{'__module__': '__main__', 'country': 'China', '__init__': <function People.__init__ at 0x1006d5620>, 'people_info': <function People.people_info at 0x10205d1e0>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}
    

    注意:调用hasattr()函数时,类中的方法也算对象的属性。

    2. getattr()函数
    描述:
    
      getattr()函数用于返回一个对象属性值
    
    语法:
    
      getattr(object,name,default)
    
    参数:
    
      object--对象
    
      name--字符串,对象属性
    
      default--默认返回值,如果不提供该参数,在没有对于属性时,将触发AttributeError。
    
    返回值:
    
      返回对象属性值
    
    class People:
        country='China'
        def __init__(self,name):
            self.name=name
    
        def people_info(self):
            print('%s is xxx' %(self.name))
    
    obj=getattr(People,'country')
    print(obj)
    #返回值China
    #obj=getattr(People,'countryaaaaaa')
    #print(obj)
    #报错
    # File "/getattr()函数.py", line 32, in <module>
    #     obj=getattr(People,'countryaaaaaa')
    # AttributeError: type object 'People' has no attribute 'countryaaaaaa'
    obj=getattr(People,'countryaaaaaa',None)
    print(obj)
    #返回值None
    
    3. setattr()函数
    描述:
    
      setattr函数,用于设置属性值,该属性必须存在
    
    语法:
    
      setattr(object,name,value)
    
     参数:
    
      object--对象
    
      name--字符串,对象属性
    
      value--属性值
    
    返回值:
    
      无
    
    class People:
        country='China'
        def __init__(self,name):
            self.name=name
    
        def people_info(self):
            print('%s is xxx' %(self.name))
    
    obj=People('aaa')
    
    setattr(People,'x',111) #等同于People.x=111
    print(People.x)
    
    #obj.age=18
    setattr(obj,'age',18)
    print(obj.__dict__)
    #{'name': 'aaa', 'age': 18}
    print(People.__dict__)
    #{'__module__': '__main__', 'country': 'China', '__init__': <function People.__init__ at 0x1007d5620>, 'people_info': <function People.people_info at 0x10215d1e0>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None, 'x': 111}
    
    4. delattr()函数
    描述:
    
      delattr函数用于删除属性
    
      delattr(x,'foobar)相当于del x.foobar
    
    语法:
    
      delattr(object,name)
    
    参数:
    
      object--对象
    
      name--必须是对象的属性
    
    返回值:
    
      无
    
    class People:
        country='China'
        def __init__(self,name):
            self.name=name
    
        def people_info(self):
            print('%s is xxx' %(self.name))
    
    delattr(People,'country') #等同于del People.country
    print(People.__dict__)
    {'__module__': '__main__', '__init__': <function People.__init__ at 0x1006d5620>, 'people_info': <function People.people_info at 0x10073d1e0>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}
    

    示例:

    class Foo:
        def run(self):
            while True:
                cmd=input('cmd>>: ').strip()
                if hasattr(self,cmd):
                    func=getattr(self,cmd)
                    func()
    
        def download(self):
            print('download....')
    
        def upload(self):
            print('upload...')
    
    # obj=Foo()
    # obj.run()
    

    相关文章

      网友评论

          本文标题:Python高级第四天

          本文链接:https://www.haomeiwen.com/subject/zkgzwctx.html