zoukankan      html  css  js  c++  java
  • 类与实例的属性及增删改查

    类的属性有两种:数据属性和函数属性

    类的数据属性是所对象共享的

    类的函数属性是绑定给对象用的

    下面分别来看一下,什么是数据属性,什么是函数属性,先简单定义一个类:

    class Chinese:
        country='China'
        def __init__(self,name):
            self.name=name
    
        def play_ball(self,ball):
            print('%s 正在打 %s' %(self.name))

    通过调用__dict__,会返回一个字典,这个字典就是属性字典:

    print(Chinese.__dict__)
    >>> {'__module__': '__main__', 'country': 'China', '__init__': <function Chinese.__init__ at 0x000002085EB7B6A8>, 'play_ball': <function Chinese.play_ball at 0x000002085EB7B730>, '__dict__': <attribute '__dict__' of 'Chinese' objects>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, '__doc__': None}

    可以看到,country、__init__、play_ball都是字典里面的key,其中country就是数据属性,另外两个就是函数属性,如果要查看类的某个属性,操作如下:

    class Chinese:
        country='China'
        def __init__(self,name):
            self.name=name
    
        def play_ball(self,ball):
            print('%s 正在打 %s' %(self.name))
    
    
    #查看
    print(Chinese.country)
    
    >>>China

    直接返回就是属性对应的值,也就是说,类名加上.,本质上就是在查看属性字典,返回的就是key对应的value,如果要修改这个属性,操作如下:

    class Chinese:
        country='China'
        def __init__(self,name):
            self.name=name
    
        def play_ball(self,ball):
            print('%s 正在打 %s' %(self.name))
    
    Chinese.country='Japan'
    print(Chinese.country)
    
    >>> Japan

    给对应的属性赋值,就是在修改这一属性,和字典的操作十分相似,所以增加和删除的属性的操作也是类似的:

    class Chinese:
        country='China'
        def __init__(self,name):
            self.name=name
    
        def play_ball(self,ball):
            print('%s 正在打 %s' %(self.name))
    
    Chinese.race='黄种人'
    print(Chinese.race)
    print(Chinese.__dict__)
    
    >>> 黄种人
    >>>{'__module__': '__main__', 'country': 'China', '__init__': <function Chinese.__init__ at 0x000002BCBDF1B6A8>, 'play_ball': <function Chinese.play_ball at 0x000002BCBDF1B730>, '__dict__': <attribute '__dict__' of 'Chinese' objects>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, '__doc__': None, 'race': '黄种人'}
    
    del Chinese.race
    print(Chinese.__dict__)
    
    >>>{'__module__': '__main__', 'country': 'China', '__init__': <function Chinese.__init__ at 0x0000025123EEB6A8>, 'play_ball': <function Chinese.play_ball at 0x0000025123EEB730>, '__dict__': <attribute '__dict__' of 'Chinese' objects>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, '__doc__': None}

    通过查看属性字典,可以看到增删的属性变化。那么实例的属性是怎样的呢?

    class Chinese:
        country='China'
        def __init__(self,name):
            self.name=name
    
        def play_ball(self,ball):
            print('%s 正在打 %s' %(self.name,ball))
    
    p1=Chinese('pengfy')
    print(p1.__dict__)
    print(p1.country)
    p1.play_ball('basketball)
    
    >>>{'name': 'pengfy'}
    >>>China
    >>>pengfy 正在打 basketball

    首先,我们看到实例的属性字典里面只有一个属性,就是实例化过程中执行类的__init__方法产生的一个name属性,那为什么还能调用其他属性?如下图:

    obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常 ,这个可以理解成函数的作用域中查找参数的情况。那么实例属性的增删改查和类一样,操作如下:

    class Chinese:
        country='China'
        def __init__(self,name):
            self.name=name
    
        def play_ball(self,ball):
            print('%s 正在打 %s' %(self.name,ball))
    p1=Chinese('alex')
    print(p1.__dict__)
    
    # 查看
    print(p1.name)
    print(p1.play_ball)
    
    #增加
    p1.age=18
    print(p1.__dict__)
    print(p1.age)
    
    # 不要修改底层的属性字典
    p1.__dict__['sex']='male'
    # print(p1.__dict__)
    # print(p1.sex)
    
    # 修改
    p1.age=19
    print(p1.__dict__)
    print(p1.age)
    
    #删除
    del p1.age
    print(p1.__dict__)

    现在再来看开始说的两句话:类的数据属性是所对象共享的,类的函数属性是绑定给对象用的

    #类的数据属性是所有对象共享的,id都一样
    print(id(Chinese.country))
    print(id(p1.country))
    print(id(p2.country))
    print(id(p3.country))
    
    '''
    1807264015728
    1807264015728
    1807264015728
    1807264015728
    '''
    
    
    
    #类的函数属性是绑定给对象使用的,obj.method称为绑定方法,内存地址都不一样
    #ps:id是python的实现机制,并不能真实反映内存地址,如果有内存地址,还是以内存地址为准
    print(Chinese.play_ball)
    print(p1.play_ball)
    print(p2.play_ball)
    print(p3.play_ball)
    '''
    <function Chinese.play_ball at 0x000001A4CB1BB730>
    <bound method Chinese.play_ball of <__main__.Chinese object at 0x000001A4CB1DEF98>>
    <bound method Chinese.play_ball of <__main__.Chinese object at 0x000001A4CB1E6198>>
    <bound method Chinese.play_ball of <__main__.Chinese object at 0x000001A4CB1E64A8>>
  • 相关阅读:
    一篇文章看懂mysql中varchar能存多少汉字、数字,以及varchar(100)和varchar(10)的区别
    SQL处理下划线分割的两边数字都分别增加值
    [LeetCode]Binary Tree Zigzag Level Order Traversal
    [LeetCode]Binary Tree Level Order Traversal
    [LeetCode]Candy
    [LeetCode]Single Number II
    [LeetCode]Single Number
    [LeetCode]Copy List with Random Pointer
    [LeetCode]Link List Cycle II
    [LeetCode]Link List Cycle
  • 原文地址:https://www.cnblogs.com/pengfy/p/10645072.html
Copyright © 2011-2022 走看看