Python高级第四天

对象属性管理

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()
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,042评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,996评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,674评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,340评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,404评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,749评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,902评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,662评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,110评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,577评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,258评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,848评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,726评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,952评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,271评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,452评论 2 348

推荐阅读更多精彩内容

  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,723评论 0 10
  • 写在前面的话 代码中的# > 表示的是输出结果 输入 使用input()函数 用法 注意input函数输出的均是字...
    FlyingLittlePG阅读 2,743评论 0 8
  • 要点: 函数式编程:注意不是“函数编程”,多了一个“式” 模块:如何使用模块 面向对象编程:面向对象的概念、属性、...
    victorsungo阅读 1,476评论 0 6
  • 高阶函数:将函数作为参数 sortted()它还可以接收一个key函数来实现自定义的排序,reversec参数可反...
    royal_47a2阅读 679评论 0 0
  • 金庸老先生的《天龙八部》可谓是武侠小说中的经典,也先后被翻拍成多版电视剧,每一版都有其独特的味道。 从我个人的角度...
    白蔷薇阅读 853评论 0 1