美文网首页Python全栈工程师
27.3-实例变量和类变量及实例属性访问顺序

27.3-实例变量和类变量及实例属性访问顺序

作者: BeautifulSoulpy | 来源:发表于2019-12-02 18:45 被阅读0次

    只有在自己的生活里活得够专注的人,才不会有精力在意他人的眼光!

    总结:

    1. 类型搞不清楚我们就没法编程了;类不可以访问实例的属性,在实例中可以访问类的属性;
    2. 整个面向对象全部是基于字典;
    3. Python中每一种对象都拥有不同的属性。函数、类都是对象,类的实例也是对象

    初始化函数中可以有多个参数,请注意第一个位置采纳数必须是self ,例如 _init_(self,name,age),
    init 函数值默认返回必须是 None

    class MyClass:
        def __init__(self):
            print('self in init = {}'.format(id(self)))
    c = MyClass()
    print('c = {}'.format(id(c)))
    #-----------------------------------------------
    self in init = 1944732789728
    c = 1944732789728
    
    

    1.实例对象instance

    类实例化后一定会获得一个对象,就是实例对象
    上例中的tom、jerry就是Person类的实例。
    _init_ 方法的第一参数 self 就是指代某一个实例。
    类实例化后,得到一个实例对象,实例对象会绑定方法,调用方法时采用jerry.showage()的方式。
    但是函数签名是showage(self),少传一个参数self吗?

    这个self就是jerry,Python会把方法的调用者作为作为第一参数self的实参传入。
    self.name就是jerry对象的name,name是保存在了jerry对象上,而不是Person类上。所以,称为实例变量;

    实例变量是每一个实例自己的变量,是自己独有的;类变量是类的变量,是类的所有实例共享的属性和方法
    class Person:
        age = 3  # 类的属性,公有的属性
        def __init__(self,name):
            self.name = name   #实例的属性
            
        def showage(self):
            print('{} is {}'.format(self.name,self.age))
    
    tom = Person('Tom')  # 实例化 初始化
    jerry = Person('Je')
    print(tom.name,tom.age)
    print(jerry.name,jerry.age)
    print(Person.age)
    
    Person.age = 30
    print(Person.age,tom.age,jerry.age)
    print(tom.showage())
    #---------------------------------------------------
    Tom 3
    Je 3
    3
    30 30 30
    Tom is 30
    

    2.类的特殊属性

    特殊属性 含义
    _name_ 对象名
    _class_ 对象的类型
    _dict_ 对象的属性的字典
    _qualname_ 类的限定名
    _repr_ 类显示

    类型搞不清楚我们就没法编程了;
    整个面向对象全部是基于字典;

    1. 类有属性名称,实例没有属性名称** _class_ _name_
    class Person:
        age = 3  # 类的属性
        def __init__(self,name):
            self.name = name   #实例的属性
            
        def showage(self):
            print('{} is {}'.format(self.name,self.age))
    tom = Person('Tom')
    
    # 类有属性名称,实例没有属性名称
    print(1,Person.__name__)
    #print(2,tom.__name__)
    print(3,tom.__class__.__name__)
    print(4,type(tom))  # type 返回为 类
    print(5,type(tom).__name__)
    print(6,'Person'.__class__.__name__)   # 字符串 属性 名称;
    print(7,type('Person'.__class__.__name__))   # 字符串 属性 ;str class 
    #------------------------------------------------------------------
    1 Person
    3 Person
    4 <class '__main__.Person'>
    5 Person
    6 str
    7 <class 'str'>
    
    
    2. _dict_ 属性
    1. 类的dict中,name 和 类 class 没有关系;所以没有name;
    class Person:
        age = 3
        def __init__(self, name):
            self.name = name
    print('----class----')
    print(Person.__class__)
    print(Person.__dict__)   # 类属性 就是 类变量
    print(sorted(Person.__dict__.items()),end = '\n\n') # 属性字典二元组;
    # 类的dict中,name 和 类 class 没有关系;所以没有name;
    #----------------------------------------------------------------------------------------------
    ----class----
    <class 'type'>
    {'__module__': '__main__', 'age': 3, '__init__': <function Person.__init__ at 0x000001C4CB1A7B70>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
    [('__dict__', <attribute '__dict__' of 'Person' objects>), ('__doc__', None), ('__init__', <function Person.__init__ at 0x000001C4CB1A7B70>), ('__module__', '__main__'), ('__weakref__', <attribute '__weakref__' of 'Person' objects>), ('age', 3)]
    
    
    #
    class Person:
        age = 3
        def __init__(self, name):
            self.name = name
    print('----class----')
    print(Person.__class__)
    print(Person.__dict__)   # 类属性 就是 类变量
    print(sorted(Person.__dict__.items()),end = '\n\n') # 属性字典二元组;
    # 类的dict中,name 和 类 class 没有关系;所以没有name;
    
    tom = Person('Tom')
    
    print('----instance----')
    print(tom.__class__)
    print(sorted(tom.__dict__.items()),end='\n\n')
    print("----tom's class----")
    print(tom.__class__.__name__)
    print(sorted(tom.__class__.__dict__.items()), end='\n\n')
    #------------------------------------------------------------------------------
    ----class----
    <class 'type'>
    {'__module__': '__main__', 'age': 3, '__init__': <function Person.__init__ at 0x000001C4CB21ED08>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
    [('__dict__', <attribute '__dict__' of 'Person' objects>), ('__doc__', None), ('__init__', <function Person.__init__ at 0x000001C4CB21ED08>), ('__module__', '__main__'), ('__weakref__', <attribute '__weakref__' of 'Person' objects>), ('age', 3)]
    
    ----instance----
    <class '__main__.Person'>
    [('name', 'Tom')]
    
    ----tom's class----
    Person
    [('__dict__', <attribute '__dict__' of 'Person' objects>), ('__doc__', None), ('__init__', <function Person.__init__ at 0x000001C4CB21ED08>), ('__module__', '__main__'), ('__weakref__', <attribute '__weakref__' of 'Person' objects>), ('age', 3)]
    
    -------------------------------
    dict_items([('__module__', '__main__'), ('age', 3), ('__init__', <function Person.__init__ at 0x000001C4CB21ED08>), ('__dict__', <attribute '__dict__' of 'Person' objects>), ('__weakref__', <attribute '__weakref__' of 'Person' objects>), ('__doc__', None)])
    
    

    类不可以访问实例的属性,在实例中可以访问类的属性;

    区别主要在于 _dict_ 的不同;

    class Person:
        age = 3
        height = 170
        def __init__(self, name,age=18):
            self.name = name
            self.age = age
    tom = Person('Tom')
    jerry = Person('Jerry',20)    
    
    print('-------age------')
    Person.age = 30
    print(Person.age, tom.age, jerry.age) # 输出什么结果
    
    print('-------height------')
    print(Person.height, tom.height, jerry.height) # 输出什么结果
    jerry.height = 175
    print(Person.height, tom.height, jerry.height) # 输出什么结果
    
    tom.height += 10
    print(Person.height, tom.height, jerry.height) # 输出什么结果
    
    Person.height += 15
    print(Person.height, tom.height, jerry.height) # 类有的,实例赋值过后,不取共有的;
    
    print('-------weight------')
    Person.weight = 70
    print(Person.weight, tom.weight, jerry.weight) # 类(共有),实例没有的取
    #----------------------------------------------------------------------------------------
    -------age------
    30 18 20
    -------height------
    170 170 170
    170 170 175
    170 180 175
    185 180 175
    -------weight------
    70 70 70
    
    
    print(tom.__dict__['height'])
    print(tom.__dict__['weight']) # 可以吗
    #--------------------------------------------------
    180
    KeyError: 'weight'
    
    
    print(tom.__dict__.items())
    print(Person.__dict__.items()) # 可以吗
    #-----------------------------------------------
    dict_items([('name', 'Tom'), ('age', 18), ('height', 180)])
    dict_items([('__module__', '__main__'), ('age', 30), ('height', 185), ('__init__', <function Person.__init__ at 0x000001C4CB1A7158>), ('__dict__', <attribute '__dict__' of 'Person' objects>), ('__weakref__', <attribute '__weakref__' of 'Person' objects>), ('__doc__', None), ('weight', 70)])
    
    
    

    总结

    1. 是类的,也是这个类所有实例的,其实例都可以访问到;是实例的,就是这个实例自己的,通过类访问不到。
      类变量是属于类的变量,这个类的所有实例可以共享这个变量。

    2. 对象(实例或类)可以动态的给自己增加一个属性。 实例dict [变量名] 和 实例.变量名 都可以访问到;
      实例的同名变量会隐藏掉类变量,或者说是覆盖了这个类变量;

    3. 实例属性的查找顺序
      指的是实例使用 .点号来访问属性,会先找自己的_dict,如果没有,然后通过属性_class找到自己的类,再去类的 dict中找
      注意,如果实例使用 dict[变量名]访问变量,将不会按照上面的查找顺序找变量了,这是指明使用字典的key查找,不是属性查找。
      class__ 找到自己的
      是指明使用字典的key

    (常量),类变量可使用全大写来命名;

    相关文章

      网友评论

        本文标题:27.3-实例变量和类变量及实例属性访问顺序

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