27.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_ 属性
- 类的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)])
总结
是类的,也是这个类所有实例的,其实例都可以访问到;是实例的,就是这个实例自己的,通过类访问不到。
类变量是属于类的变量,这个类的所有实例可以共享这个变量。对象(实例或类)可以动态的给自己增加一个属性。 实例dict [变量名] 和 实例.变量名 都可以访问到;
实例的同名变量会隐藏掉类变量,或者说是覆盖了这个类变量;实例属性的查找顺序
指的是实例使用 .点号来访问属性,会先找自己的_dict,如果没有,然后通过属性_class找到自己的类,再去类的 dict中找
注意,如果实例使用 dict[变量名]访问变量,将不会按照上面的查找顺序找变量了,这是指明使用字典的key查找,不是属性查找。
class__ 找到自己的
是指明使用字典的key
(常量),类变量可使用全大写来命名;