类,类对象和属性,类实例化
__init__方法(构造方法),self
类变量和实例变量
面向过程与面向对象
- 面向过程
- 分析出解决问题所需要的的步骤
- 用函数将这些步骤一步步实现
- 依次调用函数即可
- 面向对象
- 把构成问题事物分解成各个对象
- 建立对象的目的不是为了完成某一个步骤,而是为了描述某个事物在整个解决问题步骤中的行为
认识面向对象
- 类
- 是一类事物的共同特征的集合
- 是属性和方法的集合
- 对象
- 是类的一个实体
- 属性
- 对象状态的抽象,用数据结构来描述
- 操作
- 对象行为的抽象,用操作名和实现该操作的方法来描述
面向对象三要素
- 封装
- 继承
- 多态
python的类
- 类的定义:class关键字,大驼峰命名,类定义完成后就产生一个类对象
- 类对象及类属性
- 类对象:类的定义执行后就会生成一个类对象
- 类属性:类定义中的变量和类中定义的方法
- 实例化:创建一个类的对象的实例
__init__
方法
- 对实例进行初始化
- 初始化方法,也称构造方法,类似 java 构造方法,用来初始化成员属性和成员方法,即创建对象后,就调用对象的属性和方法。进一步理解可参看魔术方法章节中
__init__
本质 - 可以不定义,如果没定义会在实例化后隐式调用
- 不能有返回值,也就是说只能是 return None
class MyClass:
def __init__(self):
print('init')
print(MyClass) #不会调用
print(MyClass()) #调用__init__
a = MyClass() #调用__init__
self
- 当前实例本身
- 可以换名字,只是习惯用
self
表示当前实例本身
class Person():
"""A example of class"""
adress = 'shanghai' # 类变量,类属性
def __init__(self,name,age): # self 当前实例本身
self.name = name # self.name 实例的属性
self.age = age
print(self,id(self))
def show_age(self): # 类属性,类方法
print(self.age)
print(id(self))
# 一般情况下不直接使用类调用,一般先实例化
print(type(Person),type(int),type(str))
print(Person.adress)
print(Person.__doc__)
print(Person.__name__)
print(Person.show_age)
# Person.show_age() # 报错,没有self实例
print('~'*100)
# 实例化
j = Person('jerry',18)
t = Person('tom',20)
print('*'*100)
print(j,t) # 不同的实例对象
print(j.name,t.age)
Person.show_age(j) # 不报错,给了实例j
print(j.show_age,t.show_age) # bound method 将j实例与self绑定
j.show_age()
t.show_age()
print(j.adress,t.adress)
# 实例变量是每一个实例自己的变量,是自己独有的;类变量是类的变量,是类的所有实例共享的属性和方法
Person.adress = 'beijing'
print(j.adress,t.adress)
--------------------------------------------------------------------------------------
<class 'type'> <class 'type'> <class 'type'>
shanghai
A example of class
Person
<function Person.show_age at 0x0000022837181268>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<__main__.Person object at 0x000002283718CE48> 2371746319944
<__main__.Person object at 0x000002283718CDD8> 2371746319832
****************************************************************************************
<__main__.Person object at 0x000002283718CE48> <__main__.Person object at 0x000002283718CDD8>
jerry 20
18
2371746319944
<bound method Person.show_age of <__main__.Person object at 0x000002283718CE48>> <bound method Person.show_age of <__main__.Person object at 0x000002283718CDD8>>
18
2371746319944
20
2371746319832
shanghai shanghai
beijing beijing
类变量和实例变量
__name__
: 对象名__class__
:对象的类型,相当于 type(对象)__dict__
:对象的属性的字典__qualname
:类的限定名
# 仍利用上面的例子来认识几个特殊属性
print(Person.__name__,Person.__class__,type(Person),type(Person).__name__,Person.__class__.__name__)
print(Person.__dict__)
# print(j.__name__) # 报错,实例没有该属性
print('~'*100)
print(j.__class__)
print(j.__dict__,t.__dict__)
-----------------------------------
Person <class 'type'> <class 'type'> type type
{'__module__': '__main__', '__doc__': 'A example of class', 'adress': 'beijing', '__init__': <function Person.__init__ at 0x00000228371237B8>, 'show_age': <function Person.show_age at 0x000002283714AD90>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<class '__main__.Person'>
{'name': 'jerry', 'age': 18} {'name': 'tom', 'age': 20}
深入理解类变量和实例变量
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)
Person.age = 30
print(1, Person.age, tom.age, jerry.age) # 30 18 20
print(2, Person.height, tom.height, jerry.height) # 170 170 170
jerry.height = 175
print(jerry.__dict__)
print(3, Person.height, tom.height, jerry.height) # 170 170 175
tom.height += 10
print(tom.__dict__)
print(4, Person.height, tom.height, jerry.height) # 170 180 175
Person.height += 15
print(5, Person.height, tom.height, jerry.height) # 185 180 175
Person.weight = 70
print(6, Person.weight, tom.weight, jerry.weight) # 70 70 70
print(Person.__dict__)
print(7, tom.__dict__['height']) # 180
# print(8, tom.__dict__['weight']) # 报错,tom的dict中没有weight属性,不遵循.的查找顺序
-----------------------------------------------------------------------
1 30 18 20
2 170 170 170
{'name': 'Jerry', 'age': 20, 'height': 175}
3 170 170 175
{'name': 'Tom', 'age': 18, 'height': 180}
4 170 180 175
5 185 180 175
6 70 70 70
{'__module__': '__main__', 'age': 30, 'height': 185, '__init__': <function Person.__init__ at 0x0000022837181C80>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, 'weight': 70}
7 180
关于类变量和实例变量相关结论
- 类变量是属于类的变量,这个类的所有实例可以共享这个变量
- 实例变量是实例自己的,类不能访问到
- 对象(实例或类)可以动态的给自己增加一个属性(赋值即定义一个新属性)
- 实例.
__dict__[变量名]
和实例.变量名
都可以访问到实例自己的属性(注意这两种访问是有本质区别的) - 实例属性的查找顺序 (实例使用
.
点号来访问属性),会先找自己的__dict__
,如果没有,然后通过属性__class__
找到自己的类,再去类的__dict__
中找 - 注意:如果实例使用
__dict__[变量名]
访问变量,将不会按照上面的查找顺序找变量了,这是指明使用字典的 key 查找,不是属性查找
参考
- magedu