Python全栈工程师

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

2019-12-02  本文已影响0人  BeautifulSoulpy

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

总结:

  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

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

上一篇下一篇

猜你喜欢

热点阅读