设为首页 收藏本站
查看: 1766|回复: 0

[经验分享] 【循序渐进学Python】7.面向对象的核心——类型(上)

[复制链接]

尚未签到

发表于 2015-4-20 10:14:15 | 显示全部楼层 |阅读模式
  我们知道Python是一门面向对象的脚本语言。从C#的角度来看:首先Python支持多继承。Python 类型成员通常都是public的,并且所有成员函数都是virtual的(可以直接重写)。

1. 定义类型
  类是对象的模板,在Python中我们使用class关键字来定义一个类型。



1 # -- coding: utf-8 --
2 class Employee(object):
3     # self 关键字就是对象自身的一个引用(类似于C#中的this关键字)
4     def setName(self,name):
5         self.name = name
6
7     def getName(self):
8         return self.name
9
10     def greet(self):
11         print "hello,world! I'm %s" % self.name
  
  可以这样使用我们定义好的Employee类:



1 foo = Employee()
2 bob = Employee()
3 foo.setName('Sunshine')
4 bob.setName('Bob')
5
6 foo.greet() # hello,world! I'm Sunshine
7 bob.greet() # hello,world! I'm Bob
8 print foo.name # Sunshine
9 bob.name = 'Bob2' # name是Employee类的一个特性
10 bob.greet() # hello,world! I'm Bob2
  

1.1 使用新式类型
  在Python 2.2之后,对象的工作方式有了很大的改变,所有导致了在Python 2.x 版本中存在两种形式的类:Python 2.2之前的旧式类,和之后新增的新式类,新式类提供了很多新的特性(比如:super函数、property函数等),如果不需要兼容旧版本的Python代码那么做好使用新式类,在Python中声明新式类有两种方法:
  1.把赋值语句__metaclass__ = type 放置在定义模块的最开始位置,如下:



# -- coding: utf-8 --
_metaclass_ = type # 确定使用新式类
class Employee():
pass
  
  2.子类化object类型,或者是其他新式类型,如下:



class NewStyle(object):
pass
  

2. 特性和成员方法
  对象包括特性和方法,特性只是作为对象的一部分的变量,成员方法则是存储在对象内部的函数。Python中的所有方法函数在声明时显式地将第一个参数(self)表示为对象(实例),这个参数的值在方法被调用时隐式赋值:



1 # -- coding: utf-8 --
2 _metaclass_ = type # 确定使用新式类
3
4 class Class:
5     def method(self):
6         print 'I have a self'
7
8 def function():
9     print 'i don\'t...'
10
11 instance = Class()
12 instance.method() # I have a self
13 instance.method = function # 绑定一个普通的函数
14 instance.method() # i don't...
  
  通过self参数可以使用该实例的所有成员对象:



1 # -- coding: utf-8 --
2 _metaclass_ = type # 确定使用新式类
3
4 class Bird:
5     song = 'Squaawk!'
6     def sing(self):
7         print self.song
8
9 bird = Bird()
10 bird.sing() # Squaawk!
  

2.1 私有变量和私有方法
  Python其实并不存在不能访问的私有变量和私有方法。不过在Python中有一个约定:以一个下划线(_)开头的名字,应该作为一个非公共的API(不论是函数、方法或者数据成员)。我们可以这样定义一个"私有变量":



_flag = True
  
  Python解释器在遇到任何以双下划线(__)开头的标识符将会被替换为_className__spam形式,其中className是当前的类型名称,__spam就是当前的标识符名称。所以我们可以这样定义一个"私有方法":



1 # -- coding: utf-8 --
2 _metaclass_ = type # 确定使用新式类
3
4 class Secretive:
5     def __inaccessible(self):
6         print 'Bet you can\' see me...'
7
8     def accessible(self):
9         print 'The secret message is:'
10         self.__inaccessible()
11
12 s = Secretive()
13 # AttributeError: Secretive instance has no attribute '__inaccessible'
14 s.__inaccessible()
  
  因为在类的内部定义中,所有以双下划线开始的名字都被转换成前面加上单下划线和类名的形式,所以还是可以访问私有方法:



# Bet you can' see me...
s._Secretive__inaccessible()
  

3. 继承
  作为面向对象三个基本的特性之一———继承,我们可以利用它在现有类型的基础上创建自己的类型。在Python中定义派生类的方式如下:



1 # -- coding: utf-8 --
2 _metaclass_ = type # 确定使用新式类
3
4 class Person:
5     def printName(self):
6         print 'Is a Person'
7     def printHello(self):
8         print 'hello,world'
9
10 class Employee(Person):
11     # override base Method
12     def printName(self):
13         print 'Is a Employee'
14
15 person = Person()
16 person.printName() # Is a Person
17 employee = Employee()
18 employee.printName() # Is a Employee
19 employee.printHello() # hello,world
  可以看到子类继承了基类的方法,由于在Python中所有的成员函数都是virtual的,所有我们也可以选择重写基类的方法。
  

3.1 多重继承
  Python是一个多继承语言,使用多重继承的语法很简单,只需要在定义子类后面的括号中添加多个父类名称即可,如:



class C(A,B):
pass
  
  注意

  多重继承(multiple inheritance)是个很有用的工具。不过除非你特别熟悉多重继承,否则应该尽量避免使用。因为它可能会有很多出乎意料的行为。例如:一个方法从多个超类继承,那么根据继承的顺序(class语句中):先继承的类中的方法会重写后继承类中的方法。

  

3.2 查看继承关系
  Python中有两个内置函数可拥有查看继承关系:


  • 使用isinstance函数检查实例的类型
  • 使用issubclass函数检查类的继承关系
  使用方式如下:



1 # -- coding: utf-8 --
2 obj = "string"
3 print isinstance(obj,str) # True
4 print obj.__class__ #
5
6 print issubclass(bool,int) # True
7 print bool.__bases__ # (,)
  

3.3 检查对象中的方法是否存在
  使用hasattr(x,'call')来判断一个对象是否存在某个方法,如下:



1 # -- coding: utf-8 --
2 _metaclass_ = type # 确定使用新式类
3
4 class Person:
5     def PrintName(self):
6         print 'Is a Person'
7     def PrintHello(self):
8         print 'hello,world'
9
10 per = Person()
11
12 # check method Exists
13 print hasattr(per,'PrintName') # True
  

参考资料&进一步阅读
  深刻理解Python中的元类(metaclass)
  Python基础教程(第二版)
  Python入门教程——类

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-58694-1-1.html 上篇帖子: PyQt的QString和python的string的区别 下篇帖子: 每周一荐:Python Web开发框架Django
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表