Python面向对象编程基础
面向对象编程是python中的核心之一,面向对象的核心并不是概念,语法,使用有多么复杂,而是一种编程思想,并不是掌握了类创建与使用就真正掌握了面向对象编程,这需要在不断工作与练习中逐步提升;抛去代码,我们先来看现实世界的基本概念:
类:
我们最先想到的就是分类:人,动物,植物...这些都是自然界的大类;
每个类别都有自己的特征与行为,而类就是描述这些具有相同属性与方法的对象的集合。
通过一个图来全面了解面向对象基本概念:
属性:
类具有的特征,对于人类来说,身高、体重、性别等是基本属性;
方法:
类具有的功能,对于人来来说:吃饭、睡觉、工作等是通用方法;
实例:
类对应的一个具体对象,比如梅西,詹姆斯都是实际存在的人;
每个实例都有自己实际属性与方法,比如詹姆斯的姓名,体重等;
方法:
对象行为的描述,对于人类来说,吃饭,睡觉,工作都是方法;
还有一些其他基本概念,我们通过Python来实际讲解。
1:类基本语法
1.1:定义类
先来看基本语法:
class 类名:
pass
#例如:
class Person:
pass
1>class 为关键字;
2>Person为类名称;
人类有一些共同特征与方法,我们如何在类中添加?
1.2:添类属性
人类中有公共属性,例如:居住在地球,氧气和水是必需品;我们可以将其添加到类中:
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__方法,看一下调用过程。
#添加__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__方法及属性查找过程;
到这里我们对类有了基本了解,后面内容中我来介绍类的具体使用及高级使用方式。
相关文章