[Python 实战] - No.8 Python面向对象编程
2017-10-22 15:32
381 查看
面向对象三大关键:封装、继承、多态。我们从这三个方面介绍Python的面向对象编程,同时会提到Python中类的魔术方法:
1. 封装成类:
在Python中,我们使用以下方式进行类的声明:
class Person (object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
def sayHello(self):
print 'Hi~ I am %s' % (self.name)
p = Person('xiaoming', 'male')
p.sayHello()
这里需要讲解的是以下几点:
1. __init__(self,...):类似于python的构造函数,不过同时python的成员变量也需要生命在__init__(self,...)中。类内部的所有成员函数均需要一个默认的self参数,并且需要放在第一位,作用类似于我们在java中的this一样
2. 在python中,公有,私有通过下划线来表示 。__xx或者__func(self):表示该变量或者函数是私有的,在外部无法获取。公有的属性(成员变量或者函数)使用xxx 或者__xxx__来表示。我们一般直接使用变量名来表示公有的成员变量,使用__xx__来表示特殊的公有属性
3. 由于python是一个动态的语言,所以我们可以给实例化的对象绑定新的变量。这仅对于我们自己声明的类对象,内置的类是不可以的
我们可以使用dir(p)来查看p对象的属性:
python使用@classmethod 和 直接在类中创建属性来获得类方法和类变量(类似于java中的static方法和变量)
class Person(object):
count = 0
@classmethod
def objNum(cls):
return cls.count
def __init__(self, name, gender):
self.name = name
self.gender = gender
Person.count = Person.count + 1
def sayHello(self):
print 'Hi~ I am %s' % (self.name)
print Person.count # 打印 0
p = Person('xiaoming', 'male') # 执行一次__init__(self)函数, count= 1
print p.count # 打印1
print Person.objNum() #打印1
在java中,我们会声明属性,设置get和set方法,在python中同样有类似的用法:
# _*_ coding = utf-8 _*_
class Person(object):
count = 0
@classmethod
def objNum(cls):
return cls.count
def __init__(self, name, gender):
self.name = name
self.__gender = gender
Person.count = Person.count + 1
@property
def gender(self):
return self.__gender
@gender.setter
def gender(self, gender):
if gender == 'male' or gender == 'female':
self.__gender = gender
else:
raise ValueError("Wrong Gender")
def sayHello(self):
print 'Hi~ I am %s' % (self.name)
p = Person('xiaoming','male')
p.gender = 'xmale'运行程序,会抛出ValueError
、
二、继承:
在Person类下面,我们声明一个Boy类,来继承Person
# _*_ coding = utf-8 _*_
class Person(object):
count = 0
@classmethod
def objNum(cls):
return cls.count
def __init__(self, name, gender):
self.name = name
self.gender = gender
Person.count = Person.count + 1
def sayHello(self):
print 'Hi~ I am %s' % (self.name)
class Boy(Person):
def __init__(self,name,gender,hobby):
super(Boy, self).__init__(name, gender)
self.hobby = hobby
b = Boy('xiaoming','male','coding')
print b.name,b.gender,b.hobby
同时,python也可以很好的实现多根继承:
# _*_ coding = utf-8 _*_
class Person(object):
count = 0
@classmethod
def objNum(cls):
return cls.count
def __init__(self, name, gender):
self.name = name
self.gender = gender
Person.count = Person.count + 1
def sayHello(self):
print 'Hi~ I am %s' % (self.name)
class Player(object):
def __init__(self,game):
self.game = game
def playgame(self):
print 'Play game %s' % (self.game)
class Boy(Person,Player):
def __init__(self,name,gender,game,hobby):
Person.__init__(self,name, gender)
Player.__init__(self,game)
self.hobby = hobby
b = Boy('xiaoming','male','LOL','coding')
print b.name,b.gender,b.game,b.hobby
这里跟单根集成不同的地方是,我们在子类的__init__(self,...)函数中,采用了不同的方法调用父类__init__(),总结一下,有以下两种方法:
1. super(Derived,self).__init__(arg1,arg2)
2. Base.__init__(self,args1..)
第一种方法仅适用于单根,第二种单根多根均可以,推荐使用第二种
三、多态:
python的多态没有什么特殊性,也很简单。给上述Person 和Boy添加sayHello函数
# _*_ coding = utf-8 _*_
class Person(object):
count = 0
@classmethod
def objNum(cls):
return cls.count
def __init__(self, name, gender):
self.name = name
self.gender = gender
Person.count = Person.count + 1
def sayHello(self):
print 'Hi~ I am Person %s' % (self.name)
class Player(object):
def __init__(self,game):
self.game = game
def playgame(self):
print 'Play game %s' % (self.game)
class Boy(Person,Player):
def __init__(self,name,gender,game,hobby):
Person.__init__(self,name, gender)
Player.__init__(self,game)
self.hobby = hobby
def sayHello(self):
print 'Hi~ I am Boy %s' % (self.name)
def sayHello(x):
x.sayHello()
b = Boy('xiaoming','male','LOL','coding')
p = Person('xiaoming','male')
sayHello(b)
sayHello(p)
4. 魔术方法:
python的class中有很多魔术方法,这些魔术方法是我们不需要直接调用但是python的某些函数或者操作会调用的特殊方法。这类方法均为用双下划线包围的函数,例如__str__。在我们对一个对象使用print 函数的时候,就会调用到对象的__str__()函数。如果我们对类中的一些魔术方法进行覆写,就会得到我们想要的结果
例如,我们给Person添加一个__str__()方法:
# _*_ coding = utf-8 _*_
class Person(object):
count = 0
@classmethod
def objNum(cls):
return cls.count
def __init__(self, name, gender):
self.name = name
self.gender = gender
Person.count = Person.count + 1
def __str__(self):
return "I'm Person %s" % (self.name)
def sayHello(self):
print 'Hi~ I am Person %s' % (self.name)
p = Person('xiaoming','male')
print p就会打印我们的想要的 I'm Person xiaoming
在前面我们讲到了,可以给具体的实例对象绑定属性。如果我们不希望一个实例可以随意的添加属性呢?
我们可以使用__slots__,这会声明类允许的属性列表:
# _*_ coding = utf-8 _*_
class Person(object):
count = 0
__slots__ = ('name','gender')
@classmethod
def objNum(cls):
return cls.count
def __init__(self, name, gender):
self.name = name
self.gender = gender
Person.count = Person.count + 1
def __str__(self):
return "I'm Person %s" % (self.name)
def sayHello(self):
print 'Hi~ I am Person %s' % (self.name)
p = Person('xiaoming','male')
p.score = 123
print p就会报错,提示该对象没有属性score。
python中还有很多我们常用到的魔术方法,比如表示比较的__cmp__,表示长度的__len__,和将对象变为可调用对象,使得对象可以直接变成函数来返回结果的__call__等,这里不再赘述
1. 封装成类:
在Python中,我们使用以下方式进行类的声明:
class Person (object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
def sayHello(self):
print 'Hi~ I am %s' % (self.name)
p = Person('xiaoming', 'male')
p.sayHello()
这里需要讲解的是以下几点:
1. __init__(self,...):类似于python的构造函数,不过同时python的成员变量也需要生命在__init__(self,...)中。类内部的所有成员函数均需要一个默认的self参数,并且需要放在第一位,作用类似于我们在java中的this一样
2. 在python中,公有,私有通过下划线来表示 。__xx或者__func(self):表示该变量或者函数是私有的,在外部无法获取。公有的属性(成员变量或者函数)使用xxx 或者__xxx__来表示。我们一般直接使用变量名来表示公有的成员变量,使用__xx__来表示特殊的公有属性
3. 由于python是一个动态的语言,所以我们可以给实例化的对象绑定新的变量。这仅对于我们自己声明的类对象,内置的类是不可以的
我们可以使用dir(p)来查看p对象的属性:
python使用@classmethod 和 直接在类中创建属性来获得类方法和类变量(类似于java中的static方法和变量)
class Person(object):
count = 0
@classmethod
def objNum(cls):
return cls.count
def __init__(self, name, gender):
self.name = name
self.gender = gender
Person.count = Person.count + 1
def sayHello(self):
print 'Hi~ I am %s' % (self.name)
print Person.count # 打印 0
p = Person('xiaoming', 'male') # 执行一次__init__(self)函数, count= 1
print p.count # 打印1
print Person.objNum() #打印1
在java中,我们会声明属性,设置get和set方法,在python中同样有类似的用法:
# _*_ coding = utf-8 _*_
class Person(object):
count = 0
@classmethod
def objNum(cls):
return cls.count
def __init__(self, name, gender):
self.name = name
self.__gender = gender
Person.count = Person.count + 1
@property
def gender(self):
return self.__gender
@gender.setter
def gender(self, gender):
if gender == 'male' or gender == 'female':
self.__gender = gender
else:
raise ValueError("Wrong Gender")
def sayHello(self):
print 'Hi~ I am %s' % (self.name)
p = Person('xiaoming','male')
p.gender = 'xmale'运行程序,会抛出ValueError
、
二、继承:
在Person类下面,我们声明一个Boy类,来继承Person
# _*_ coding = utf-8 _*_
class Person(object):
count = 0
@classmethod
def objNum(cls):
return cls.count
def __init__(self, name, gender):
self.name = name
self.gender = gender
Person.count = Person.count + 1
def sayHello(self):
print 'Hi~ I am %s' % (self.name)
class Boy(Person):
def __init__(self,name,gender,hobby):
super(Boy, self).__init__(name, gender)
self.hobby = hobby
b = Boy('xiaoming','male','coding')
print b.name,b.gender,b.hobby
同时,python也可以很好的实现多根继承:
# _*_ coding = utf-8 _*_
class Person(object):
count = 0
@classmethod
def objNum(cls):
return cls.count
def __init__(self, name, gender):
self.name = name
self.gender = gender
Person.count = Person.count + 1
def sayHello(self):
print 'Hi~ I am %s' % (self.name)
class Player(object):
def __init__(self,game):
self.game = game
def playgame(self):
print 'Play game %s' % (self.game)
class Boy(Person,Player):
def __init__(self,name,gender,game,hobby):
Person.__init__(self,name, gender)
Player.__init__(self,game)
self.hobby = hobby
b = Boy('xiaoming','male','LOL','coding')
print b.name,b.gender,b.game,b.hobby
这里跟单根集成不同的地方是,我们在子类的__init__(self,...)函数中,采用了不同的方法调用父类__init__(),总结一下,有以下两种方法:
1. super(Derived,self).__init__(arg1,arg2)
2. Base.__init__(self,args1..)
第一种方法仅适用于单根,第二种单根多根均可以,推荐使用第二种
三、多态:
python的多态没有什么特殊性,也很简单。给上述Person 和Boy添加sayHello函数
# _*_ coding = utf-8 _*_
class Person(object):
count = 0
@classmethod
def objNum(cls):
return cls.count
def __init__(self, name, gender):
self.name = name
self.gender = gender
Person.count = Person.count + 1
def sayHello(self):
print 'Hi~ I am Person %s' % (self.name)
class Player(object):
def __init__(self,game):
self.game = game
def playgame(self):
print 'Play game %s' % (self.game)
class Boy(Person,Player):
def __init__(self,name,gender,game,hobby):
Person.__init__(self,name, gender)
Player.__init__(self,game)
self.hobby = hobby
def sayHello(self):
print 'Hi~ I am Boy %s' % (self.name)
def sayHello(x):
x.sayHello()
b = Boy('xiaoming','male','LOL','coding')
p = Person('xiaoming','male')
sayHello(b)
sayHello(p)
4. 魔术方法:
python的class中有很多魔术方法,这些魔术方法是我们不需要直接调用但是python的某些函数或者操作会调用的特殊方法。这类方法均为用双下划线包围的函数,例如__str__。在我们对一个对象使用print 函数的时候,就会调用到对象的__str__()函数。如果我们对类中的一些魔术方法进行覆写,就会得到我们想要的结果
例如,我们给Person添加一个__str__()方法:
# _*_ coding = utf-8 _*_
class Person(object):
count = 0
@classmethod
def objNum(cls):
return cls.count
def __init__(self, name, gender):
self.name = name
self.gender = gender
Person.count = Person.count + 1
def __str__(self):
return "I'm Person %s" % (self.name)
def sayHello(self):
print 'Hi~ I am Person %s' % (self.name)
p = Person('xiaoming','male')
print p就会打印我们的想要的 I'm Person xiaoming
在前面我们讲到了,可以给具体的实例对象绑定属性。如果我们不希望一个实例可以随意的添加属性呢?
我们可以使用__slots__,这会声明类允许的属性列表:
# _*_ coding = utf-8 _*_
class Person(object):
count = 0
__slots__ = ('name','gender')
@classmethod
def objNum(cls):
return cls.count
def __init__(self, name, gender):
self.name = name
self.gender = gender
Person.count = Person.count + 1
def __str__(self):
return "I'm Person %s" % (self.name)
def sayHello(self):
print 'Hi~ I am Person %s' % (self.name)
p = Person('xiaoming','male')
p.score = 123
print p就会报错,提示该对象没有属性score。
python中还有很多我们常用到的魔术方法,比如表示比较的__cmp__,表示长度的__len__,和将对象变为可调用对象,使得对象可以直接变成函数来返回结果的__call__等,这里不再赘述
相关文章推荐
- Python爬虫开发与项目实战 1:回顾Python编程
- Python实战四.逻辑回归
- python面向对象编程对象和实例的理解
- Python-OpenCV实战二(图像的表示和处理)
- Python面向对象编程基础
- Python学习笔记 === python面向对象编程
- Python爬虫实战一之爬取糗事百科段子
- Python实战:美女图片下载器,海量图片任你下载
- Python 学习笔记(Machine Learning In Action)K-近邻算法(KNN)机器学习实战
- Python实战之自己主动化评论
- Python机器学习实战之支持向量机概念篇
- Python基础之-面向对象编程(引言)
- python实战串口助手---9串口接收显示
- 用Python和Pygame写游戏-从入门到精通(实战一:涂鸦画板)
- python爬虫实战二之爬取百度贴吧帖子
- python十个实战项目
- Python爬虫入门实战一
- python3数据科学入门实战
- python3 [入门基础实战] 爬虫入门之爬取豆瓣读书随笔页面
- Python爬虫实战入门二:从一个简单的HTTP请求开始