1.面向对象介绍
目录:
1.简单介绍
2.类的定义
3.总结
1.简单介绍
类class:
类是抽象的概念,是万事万物的抽象,是一类事物的共同特征的集合
用计算机语言描述类,是属性和方法的集合
对象:instance、object
对象是类的具象,是一个实体
对于我们每个人这个个体,都是抽象概念人类的不同的实体
属性:它是对象状态的抽象,用数据结构来描述
操作:它是对象行为的抽象,用操作名和实现该操作的方法来描述
2.类的定义
2.1类对象及类属性
类对象:类的定义执行后会生成一个类对象
类的属性:类定义中的变量和类中定义的方法都是类的属性
类变量:例中的x、foo都是类的属性,doc也是类的特殊属性
foo方法是类的属性,foo是方法method,本质上就是普通函数对象,一般要求至少有一个参数。第一个形式参数可以是self,指代当前实例本身
>>> class MyClass:
... """A example class"""
... x = 'abc' #类属性
... def foo(self): #类属性foo,也是方法
... return 'My Class'
>>> print(MyClass.x)
abc
>>> print(MyClass.foo)
<function MyClass.foo at 0x7ff5ab54e820>
>>> print(MyClass.foo(1))
My Class
>>> print(MyClass.__doc__)
A example class
2.2实例化
在类对象名称后面加上一个括号,就调用类的实例化方法,完成实例化。
每次实例化后获得的实例,是不同的实例,即使是使用同样的参数实例化,也得到不一样的对象。
Python类实例化后,会自动调用init方法。这个方法第一个形式参数必须留给self。
>>> a = MyClass()
>>> b = MyClass()
__init__方法:MyClass()实际上调用的是init(self)方法,可以不定义,如果没有定义会在实例化后隐式调用
>>> class MyClass:
... def __init__(self):
... print('init')
>>> print(MyClass) #不调用__init__函数
<class '__main__.MyClass'>
>>> print(MyClass()) #调用__init__函数
init
<__main__.MyClass object at 0x7f8c5d492e50>
>>> a = MyClass() #调用__init__函数
init
初始化函数可以多个参数,第一个参数必须是self
init()方法不能有返回值,只能return None
>>> class Person:
... def __init__(self,name,age):
... self.name = name
... self.age = age
... def showage(self):
... print('{} is {}'.format(self.name,self.age))
>>> tom = Person('Tom',20)
>>> jerry = Person('Je',25)
>>> print(tom.name,jerry.age)
Tom 25
>>> jerry.age += 1
>>> print(jerry.age)
26
>>> jerry.showage()
Je is 26
2.3实例对象instance
1.类实例化后一定会获得一个类的实例,就是实例对象。tom,jerry就是Person类的实例。init方法的第一个参数self就是指代某一个实例自身。
2.类实例化后,得到一个实例对象,调用方法是采用jerry.showage()的方式,实例对象会绑定到方法上。但是该函数签名是showage(self)
3.这个self就是jerry,jerry.showage()调用时,会把方法的调用者jerry实例作为第一参数self的实参传入。self.name就是jerry对象的name,name是保存在了jerry对象上,而不是Person类上,所以称为实例变量。
>>> class MyClass:
... def __init__(self):
... print(1,'self in init = {}'.format(id(self)))
... def showself(self):
... print(2,'self in showage() = {}'.format(id(self)))
>>> c = MyClass()
1 self in init = 139888129777232
>>> print(3,'c = {}'.format(id(c)))
3 c = 139888129777232
>>> c.showself()
2 self in showage() = 139888129777232
2.4实例变量和类变量
实例变量是每一个实例自己的变量,是自己独有的;
类变量是类变量,是类的所有实例共享的属性和方法。
>>> class Person:
... age = 3
... def __init__(self,name):
... self.name = name
>>> tom = Person('Tom')
>>> jerry = Person('Jerry')
>>> print(tom.name,tom.age)
Tom 3
>>> print(jerry.name,jerry.age)
Jerry 3
>>> print(Person.age)
3
>>> Person.age = 30
>>> print(Person.age,tom.age,jerry.age)
30 30 30
>>> print(Person.__dict__)
{
'__module__': '__main__',
'age': 30,
'__init__': <function Person.__init__ at 0x7f67ccbac820>,
'__dict__': <attribute '__dict__' of 'Person' objects>,
'__weakref__': <attribute '__weakref__' of 'Person' objects>,
'__doc__': None
}
>>> print(tom.__dict__)
{'name': 'Tom'}
>>> print(jerry.__dict__)
{'name': 'Jerry'}
2.5 几个特殊属性
__name__ 对象名
__class__ 对象的类型
__dict__ 对象属性的字典
__qualname__ 类的限定名
Note:Python中每一种对象都拥有不同的属性,函数、类都是对象,类的实例也是对象
Person类的访问:
>>> class Person:
... age = 3
... def __init__(self,name):
... self.name = name
>>> print(Person.__class__,type(Person))
<class 'type'> <class 'type'>
>>> print(Person.__dict__)
{
'__module__': '__main__',
'age': 3,
'__init__': <function Person.__init__ at 0x7f24de9df820>,
'__dict__': <attribute '__dict__' of 'Person' objects>,
'__weakref__': <attribute '__weakref__' of 'Person' objects>,
'__doc__': None
}
>>> print(sorted(Person.__dict__.items()),end='\n\n')
[
('__dict__', <attribute '__dict__' of 'Person' objects>),
('__doc__', None),
('__init__', <function Person.__init__ at 0x7f24de9df820>),
('__module__', '__main__'),
('__weakref__', <attribute '__weakref__' of 'Person' objects>),
('age', 3)
]
tom实例的访问:
>>> tom = Person('Tom')
>>> print(tom.__class__,type(tom))
<class '__main__.Person'> <class '__main__.Person'>
>>> print(tom.__dict__)
{'name': 'Tom'}
>>> print(sorted(tom.__dict__.items()),end='\n\n')
[('name', 'Tom')]
>>> print(tom.__class__.__dict__)
{
'__module__': '__main__',
'age': 3,
'__init__': <function Person.__init__ at 0x7f24de9df820>,
'__dict__': <attribute '__dict__' of 'Person' objects>,
'__weakref__': <attribute '__weakref__' of 'Person' objects>,
'__doc__': None
}
>>> print(sorted(tom.__class__.__dict__.items()),end='\n\n') #打印type(tom).__dict__比较看看
[
('__dict__', <attribute '__dict__' of 'Person' objects>),
('__doc__', None),
('__init__', <function Person.__init__ at 0x7f24de9df820>),
('__module__', '__main__'),
('__weakref__', <attribute '__weakref__' of 'Person' objects>),
('age', 3)
]
上例中,可以看到类属性保存在类的dict中,实例属性保存在实例的dict中。
如果从实例访问类的属性,也可以借助class找到所属的类,再通过类来访问类属性,例如tom.class.age。
3.总结
eg:
>>> class Person:
... age = 3
... height = 170
... def __init__(self,name,age=18):
... self.name = name
... self.age = ageT
>>> tom = Person('Tom') #实例化、初始化
>>> jerry = Person('Jerry',20)
>>> Person.age = 30
>>> print(1,Person.age,tom.age,jerry.age)
1 30 18 20
>>> print(2,Person.height,tom.height,jerry.height)
2 170 170 170
>>> jerry.height = 175
>>> print(3,Person.height,tom.height,jerry.height)
3 170 170 175
>>> tom.height += 10
>>> print(4,Person.height,tom.height,jerry.height)
4 170 180 175
>>> Person.height += 15
>>> print(5,Person.height,tom.height,jerry.height)
5 185 180 175
>>> Person.weight = 70
>>> print(6,Person.weight,tom.weight,jerry.weight)
6 70 70 70
>>> print(7,tom.__dict__['height'])
7 180
>>> print(8,tom.__dict__['weight'])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'weight'
>>> print(tom.__dict__)
{
'name': 'Tom',
'age': 18,
'height': 180
}
>>> print(Person.__dict__)
{
'__module__': '__main__',
'age': 30, 'height': 185,
'__init__': <function Person.__init__ at 0x7ff3549bb820>,
'__dict__': <attribute '__dict__' of 'Person' objects>,
'__weakref__': <attribute '__weakref__' of 'Person' objects>,
'__doc__': None,
'weight': 70
}
1.是类的也是这个类所有实例的,其实例都可以访问到
2.是实例的,就是这个实例自己的,通过类访问不到
3.类变量是属于类的变量,这个类的所有实例可以共享这个变量
4.对象(实例或类)可以动态的给自己增加一个属性(赋值即定义一个新属性)
instance.__dict__[variable_name]和instance.variable_name都可以访问到实例自己的属性
#以上两种访问是有本质却别的
实例的同名变量会隐藏掉类变量,或者说是覆盖了整个类变量,但是注意类变量还在那里,并没有真正被覆盖。
5.实例属性的查找顺序
指的是实例使用”.“号来访问属性,会先找自己的__dict__,如果没有,然后通过属性__class__找到自己的类,再去找类的__dict__中找
如果实例使用__dict__[variable_name]访问变量,将不会按照上面的查找顺序找变量了,这是指明使用字典的key查找,不是属性查找,此外,类变量可使用全大写来命名。