我们下面的探讨基于Python3,我实际测试使用的是Python3.2,Python3与Python2在类函数的类型上做了改变

1,类定义语法 

Python类定义以关键字class开头,一个类定义例子

 class MyClass:
"""this is an example"""
i = 123
def f(self):
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来直接引用,可以去获取类的属性,也可以对其赋值修改类的属性,也可以为类对象增加新的属性。

如对于上面的类对象,可以如下操作:

 def add(self, x, y):
return x+y MyClass.i = 4321 #将属性MyClass.i绑定到一个新的int对象
MyClass.add = add #添加一个新的属性,绑定到一个函数对象上

2.2 实例化

类对象还支持的另一个操作是实例化,实例化的语法就像函数调用一样,类名加上括号。

x = MyClass()

这创建了一个实例对象(instance object),并在当前域中用名字x和这个对象绑定。

从一个类对象实例化出一个实例对象后,也引入了一个实例对象名字空间,这个名字空间会用类对象的名字空间去初始化。

当然实例化的时候可以进行初始化设置,可以带一些参数,这就需要类去定义__init__()方法:

 class Complex:
def __init__(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
c = Complex(2, -3)
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)
<class 'function'>
>>> x = MyClass()
>>> type(x.f)
<class 'method'>

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

使用MyClass.f和x.f

 print(MyClass.f(x))
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上去,代码如下:

 class MyClass:
"""this is an example"""
i = 1234
def f(self):
return 'hello world'
def add(self, x, y):
return x+y x = MyClass()
x.f = MyClass.add print(x.f(x,3,4))
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行的调用说明了这点。

Python类的探讨的更多相关文章

  1. Python基础-类的探讨(class)

    Python基础-类的探讨(class) 我们下面的探讨基于Python3,我实际测试使用的是Python3.2,Python3与Python2在类函数的类型上做了改变 1,类定义语法  Python ...

  2. python 类(object)的内置函数

    python 类(object)的内置函数 # python 类(object)的内置函数 ### 首先 #### 以__双下划线开头的内置函数 __ #### __往往会在某些时候被自动调用,例如之 ...

  3. Python类中super()和__init__()的关系

    Python类中super()和__init__()的关系 1.单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(sel ...

  4. LightMysql:为方便操作MySQL而封装的Python类

    原文链接:http://www.danfengcao.info/python/2015/12/26/lightweight-python-mysql-class.html mysqldb是Python ...

  5. python 类属性与方法

    Python 类属性与方法 标签(空格分隔): Python Python的访问限制 Python支持面向对象,其对属性的权限控制通过属性名来实现,如果一个属性有双下划线开头(__),该属性就无法被外 ...

  6. python 类以及单例模式

    python 也有面向对象的思想,则一切皆对象 python 中定义一个类: class student: count = 0         books = [] def __init__(self ...

  7. Python类的特点 (1):构造函数与方法

    Python中,类的特点: #encoding:utf-8 class Parent(object): x=1 #x是Parent类的属性(字段) def __init__(self): print ...

  8. Python类属性,实例属性

    1.Python类数据属性:定义在类里面但在函数外面的变量,它们都是静态的. #一段很简单的代码,但反应了很多 >>> class A(): a=1 #一个类里面有个属性a > ...

  9. python类及其方法

    python类及其方法 一.介绍 在 Python 中,面向对象编程主要有两个主题,就是类和类实例类与实例:类与实例相互关联着:类是对象的定义,而实例是"真正的实物",它存放了类中 ...

随机推荐

  1. Java-利用spring发送邮件

    最近项目中需要发送邮件的功能,于是百度一大把例子.但是有很多都是一样的,一点特点都没有.所以决定整理一番.         在spring2.X以后的版本就提供了org.springframework ...

  2. Codeforces 443 B Kolya and Tandem Repeat【暴力】

    题意:给出一个字符串,给出k,可以向该字符串尾部添加k个字符串,求最长的连续重复两次的子串 没有想出来= =不知道最后添加的那k个字符应该怎么处理 后来看了题解,可以先把这k个字符填成'*',再暴力枚 ...

  3. 4.0之后的hibernate获取sessionFactory

    static{ Configuration config=new Configuration().configure(); ServiceRegistry resgistry = new Servic ...

  4. BZOJ 3624 免费道路

    第一反应:这不先0后1做并查集就行了吗? 然后WA了... 哦....啊?哦...233 如果按顺序做并查集,有些0的边可能很重要(只能由它作为0连起两个联通块),但并没有被选. 于是先按1做并查集, ...

  5. 一个基于WebGL的仿真3D水池有逼真的水波纹效果

    最近在研究WebGL,看到国外很多高手做的很多超炫的3D效果,无比羡慕.忍不住把效果趴下来研究,下面介绍一个逼真的游泳池中浮动小球的效果.效果非常绚丽,功能强大.示例可切换观察水池的视角,不同视角考虑 ...

  6. Myeclipse提示失效?

  7. HDU 产生冠军 2094

    解题思路:这题重在分析,可能你知道的越多,这题想得越多,什么并查集,什么有向图等. 事实是,我们会发现,只要找到一个,并且仅有一个的入度为0的点,说明可以找出   冠军.若入度为0的点一个都没有,说明 ...

  8. SeuRain的归来

    不知不觉二十载寒窗苦读要结束了,还没有到回顾过去的时候.马上进入研三了,现在要努力加油了.还记得曾经的那个在凌晨两点奋战的宇么?归来吧!

  9. 关于TCP/UDP缓存

    1.修订单个socket的缓冲区大小:通过setsockopt使用SO_RCVBUF来设置接收缓冲区,该参数在设置的时候不会与rmem_max进行对比校验,但是如果设置的大小超过rmem_max的话, ...

  10. JAVA遍历一个文件夹中的所有文件

    在实际项目中给定一文件夹,得到这个文件夹下所有的文件这样的需求并不是很多,更多的是查找或是删除某一具体的文件 import java.io.File; import java.util.ArrayLi ...