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

[经验分享] Python类的探讨

[复制链接]

尚未签到

发表于 2015-4-20 10:05:20 | 显示全部楼层 |阅读模式
  我们下面的探讨基于Python3,我实际测试使用的是Python3.2,Python3与Python2在类函数的类型上做了改变
  
  1,类定义语法
  Python类定义以关键字class开头,一个类定义例子



1 class MyClass:
2         """this is an example"""
3         i = 123
4         def f(self):
5                 return "hello world"
  当类定义一进入的时候,也就是class关键字一遇到的时候,就开启了一个新的名字空间(namespace),并且被作为当前的局部域。
  只要没有进入新的局部域,类定义里面的赋值语句和函数定义都会把名字绑定在作为当前域的这个class namespace中。而类定义结束的时候,这个当前域就退出了,会重新进入到类定义之前的局部域(基本上是全局域)。
  类定义结束的时候,一个类对象(class object)也被创建了,并且这个类对象会以定义时使用的名字绑定在类定义之前的那个局部域中。
  上面的类定义在类的namespace中绑定了三个对象


  • i : int
  • f : 一个函数对象
  • __doc__: 一个str对象(第2行三引号对类进行注释)
  
  
  2,类对象和实例对象(Class Object and Instance Object)
  类对象支持两种操作,属性引用(attribute)和实例化(instantiation)。
  2.1 属性引用
  类名字空间的所有name都是这个类的属性,可以通过ClassName.Attr来直接引用,可以去获取类的属性,也可以对其赋值修改类的属性,也可以为类对象增加新的属性。
  如对于上面的类对象,可以如下操作:



1 def add(self, x, y):
2     return x+y
3
4 MyClass.i = 4321   #将属性MyClass.i绑定到一个新的int对象
5 MyClass.add = add  #添加一个新的属性,绑定到一个函数对象上
  
  2.2 实例化
  类对象还支持的另一个操作是实例化,实例化的语法就像函数调用一样,类名加上括号。



x = MyClass()
  这创建了一个实例对象(instance object),并在当前域中用名字x和这个对象绑定。
  从一个类对象实例化出一个实例对象后,也引入了一个实例对象名字空间,这个名字空间会用类对象的名字空间去初始化。
  
  当然实例化的时候可以进行初始化设置,可以带一些参数,这就需要类去定义__init__()方法:



1 class Complex:
2     def __init__(self, realpart, imagpart):
3         self.r = realpart
4         self.i = imagpart
5 c = Complex(2, -3)
6 print(c.r, c.i)
  输出:(2, -3)
  
  [对实例对象来说,支持属性的哪些操作,下面的的是可以为一个实例的属性重新绑定对象,我记得django view中的request是可以增加属性的 ]??
  
  
  3,方法对象(Method Object)
  可以这么理解:方法是属于某一个对象的函数。(method is a function that "belongs to " an object)
  对于Python3来说,在class中的函数属性就是函数对象(function object),而实例中的函数类属性则是方法对象(method object)


  • 注:在Python2.7中class和instance中的函数属性都是方法对象,一个未绑定(unbound),一个是绑定了实例对象的
  对于我们上面定义的类MyClass以及MyClass的实例x,用Python3.2测试一下



>>> type(MyClass.f)

>>> x = MyClass()
>>> type(x.f)

  可以看到在Python3中x.f是method而MyClass.f是function。
  
  使用MyClass.f和x.f



1 print(MyClass.f(x))
2 print(x.f())
  会输出两行一样的:hello world
  
  记住,对于Python3来说,MyClass.f就是一个普通的函数对象,而它要求了一个参数self,根据函数的定义,当然我们可以给self传进去任何一个类型的对象,事实证明也是可以的



print(MyClass.f(5))
  依然会输出:hello world


  • 注意:如果使用Python2.7的话,这样会报错,因为Python2.7是把MyClass.f作为method的,而method调用第一个参数必须是这个类的实例对象。
  
  现在我们再看看method object,简称为method。
  method在调用时其第一个参数必须为method"所属的"对象,但是我们实际使用的时候都是这样做的:
  >>>x.f()
  其实编译器大概是这么做的,首先它确定x.f是一个method(注:x.f也可以不是一个method而是一个function,下面我们会看到),然后它去搜寻x所属的class的定义,找到f,然后由x和f去生成一个method object,并把x作为第一个参数进行调用。
  
  现在我们试着把x.f给绑定到一个function上去,代码如下:



1 class MyClass:
2     """this is an example"""
3     i = 1234
4     def f(self):
5         return 'hello world'
6     def add(self, x, y):
7         return x+y
8
9 x = MyClass()
10 x.f = MyClass.add
11
12 print(x.f(x,3,4))
13 print(x.add(8, 8))
  输出:7
  16
  还是这个MyClass,我们在类MyClass中定义了一个add,我们已经知道这是function。
  我们把实例属性x.f绑定到函数对象MyClass.add,所以现在x.f是function而不是method了,第12行的调用也说明了这一点,如果没有第一个参数x,是会报错的,同样的实例x也有method  add,不用传入x,第13行的调用说明了这点。

运维网声明 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-58686-1-1.html 上篇帖子: Python核心编程笔记(1)——Python到底能做什么呢? 下篇帖子: Python入门(一):一句话统计文章不重复汉字数
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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