面向对象编程是Python中的核心之一,面向对象的核心并非概念,语法,使用有多么复杂,而是一种编程思想,并非掌握了类建立与使用就真正掌握了面向对象编程,这须要在不断工做与练习中逐步提高;抛去代码,咱们先来看现实世界的基本概念:python
咱们最早想到的就是分类:人,动物,植物...这些都是天然界的大类;
每一个类别都有本身的特征与行为,而类就是描述这些具备相同属性与方法的对象的集合。
经过一个图来全面了解面向对象基本概念:编程
类具备的特征,对于人类来讲,身高、体重、性别等是基本属性;ide
类具备的功能,对于人来来讲:吃饭、睡觉、工做等是通用方法;函数
类对应的一个具体对象,好比梅西,詹姆斯都是实际存在的人;
每一个实例都有本身实际属性与方法,好比詹姆斯的姓名,体重等;学习
对象行为的描述,对于人类来讲,吃饭,睡觉,工做都是方法;ui
还有一些其余基本概念,咱们经过Python来实际讲解。code
先来看基本语法:对象
class 类名: pass #例如: class Person: pass
1>class 为关键字;
2>Person为类名称;接口
人类有一些共同特征与方法,咱们如何在类中添加?ip
人类中有公共属性,例如:居住在地球,氧气和水是必需品;咱们能够将其添加到类中:
class Person: #居住星球 start = 'Earth' #必须品:水,实物,氧气 needlist = ['water', 'food','oxygen']
咱们能够直接访问这些属性:
print(Person.star) print(Person.needlist)
输出结果:
print(Person.star) print(Person.needlist)
人类有一些共同方法,例如:吃饭,睡觉,工做等,如何添加到类中?
python中类方法分为实例方法,类方法,静态方法,其余语言中也有这些概念,可能语法不一样,可是基本概念相似,咱们先来看实例方法,基本语法以下:
class 类名: def func_name(self, *args, **kwargs): pass
1>类中添加实例方法,与定义函数相似,def关键字+方法名+参数;
2>实例方法的第一个参数必须是self,这是基本语法;
3>实例方法不能直接调用,只有具体对象才能调用;
添加人类方法:sleep,eat,work,say;代码实现以下:
class Person: #居住星球 star = 'Earth' #必须品:水,实物,氧气 needlist = ['water', 'food','oxygen'] #第一个参数:self def eat(self, foodlist): pass def sleep(self): pass def work(self, tasklist): pass def say(self, what): pass
后面实际工做与学习中,若是咱们对类掌握十分熟悉,能够先把属性与接口定义出来,而后逐步完善每个方法就能够,为了方便后面观察调用过程,咱们给每一个方法加上输出信息:
class Person: #居住星球 star = 'Earth' #必须品:水,实物,氧气 needlist = ['water', 'food','oxygen'] #第一个参数:self def eat(self, foodlist): print('I eat:',foodlist) def sleep(self): print('I am sleep now') def work(self, tasklist): print('my work is:', tasklist) def say(self, what): print('I say:', what)
类定义好了,咱们如何来使用呢,来建立具体人的对象,实例化:
建立一个对象,对于刚才例子咱们可使用下面方式:
p1 = Person() p2 = Person()
p2与p2就是Person类对应的两个对象,也成为实例,如何调用eat, sleep等方法?
使用实例p1,p2仍是Person?当有疑问时,咱们能够经过实际操做验证:
p1.sleep() Person.sleep()
输出结果:
I am sleep now --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-6-3a15402f300a> in <module>() 1 p1.sleep() ----> 2 Person.sleep() TypeError: sleep() missing 1 required positional argument: 'self'
第一条语句正常输出,第二条是错误的,由于须要参数self;
这里咱们有必要把这个搞清楚:
1>Person类中的方法都是实例方法,他的第一个参数必须是self,那么self到底是谁?
2>若是是实例直接调用,那么self,就是实例本身,好比,p1,p2;
3>类不能直接调用实例方法,由于没有与实例进行绑定,可是能够换一种方式调用;
下面咱们来验证self到底是谁,对代码进行修改:
#定义最简Person类 class Person: def whoami(self): print('I am 0x%x'%id(self)) #建立对象 p = Person() #id函数:显示对象内存地址 print('p id:0x%x'%id(p)) #对象调用实例方法 p.whoami() #不推荐使用,只是用来理解实例方法, #实例方法第一参数必须是类的一个实例 Person.whoami(p)
输出结果( 输出地址可能不一样):
p id:0x7f99c06d4fd0 I am 0x7f99c06d4fd0 I am 0x7f99c06d4fd0
经过这里例子,但愿对你们理解实例方法有帮助。
定义人类了,但人有名称,年龄等本身特征,如何在实例化时候指定这些属性,这里咱们须要使用__init__方法,咱们先来添加一个__init__方法,看一下调用过程。
#添加__init__方法 class Person: def __init__(self, name): print('call init name:', name) #实例化时,添加名称 p1 = Person('sun') p2 = Person('li')
输出结果为:
call init name: sun call init name: li
咱们并无显示调用__init__方法,这是怎么回事?
实例化过程会默认调用__init__方法,调用__init__时,实例已经建立出来,这个方法的参数对应实例化时传递参数,目的:初始化对象的属性。好比名称,如何添加实例属性?
首先来看类属性,咱们人类都属于地球,因此咱们添加一个属性:
class Person: #居住星球 star = 'Earth' name = 'unknow' p1 = Person() #访问star与name print(p1.star, p1.name)
输出结果:
Earth unknow
这里咱们访问p1的star与name其实访问的是类属性。
添加实例属性:
#既简单又粗暴 p1.name = 'sun' print(p1.star, p1.name)
输出结果:
Earth sun
思考问题:这时候Person类中的name是什么?作实验验证:
print('p1.name:',p1.name) print('Person.name:',Person.name)
输出结果:
p1.name: sun Person.name: unknow
分析下上面步骤:
1>p1.name=sun,修改了什么?它只是对p1增长name属性,值为sun,对其余对象与Person类没有任何影响;
2>p1与Person中有了name属性,p1访问时,选择哪一个?若是实例中有name属性,使用实例中属性,若是没有,去类中查找,若类中不存在报异常。
下面咱们在__init__方法中直接添加实力属性,实例化时直接添加名称与年龄:
class Person: name = 'unknow' def __init__(self, name, age): self.name = name self.age = age def selfintroduction(self): print('my name is %s, I am %d years old.'%(self.name, self.age)) p1 = Person('sun', 10) p1.selfintroduction()
输出结果:
my name is sun, I am 10 years old.
咱们有个问题,实例中的name与age被放到哪里,经过__dict__看下:
print('Person:',Person.__dict__) print('p1:',p1.__dict__)
输出结果:
Person: {'__module__': '__main__', 'name': 'unknow', '__init__': <function Person.__init__ at 0x7f99c0748d90>, 'selfintroduction': <function Person.selfintroduction at 0x7f99c0748bf8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None} p1: {'name': 'sun', 'age': 10}
经过输出信息,咱们能够看到这些值存放方式,能够经过这种方式直接赋予实例新的属性,可是咱们不推荐这种方式。
这节咱们主要内容:
1>面向对象基本概念:类,对象,属性,方法;
2>Python中类定义及实例化过程;
3>__init__方法及属性查找过程;
到这里咱们对类有了基本了解,后面内容中我来介绍类的具体使用及高级使用方式。