Python基础-类的探讨(class)

我们下面的探讨基于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)

对实例对象来说,仅支持属性引用操作,实例对象的属性包括数据属性和方法(data attributes and method)

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

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行的调用说明了这点。

 
 
分类: Python

Python基础-类的探讨(class)的更多相关文章

  1. python基础——类和实例

    python基础——类和实例 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都 ...

  2. Python基础-类

    Python基础-类 @(Python)[python, python基础] 写在前面 如非特别说明,下文均基于Python3 摘要 本文重点讲述如何创建和使用Python类,绑定方法与非绑定方法的区 ...

  3. python基础——类名称空间与对象(实例)名称空间

    python基础--类名称空间与对象(实例)名称空间 1 类名称空间 创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性 而类的良好总属性:数据属性和函数属性 其中类 ...

  4. Python菜鸟之路:Python基础-类(1)——概念

    什么是类? 在python中,把具有相同属性和方法的对象归为一个类(class).类是对象的模板或蓝图,类是对象的抽象化,对象是类的实例化.类不代表具体的事物,而对象表示具体的事物. 类的创建 cla ...

  5. python基础-----类和实例

    在python中,首字母大写的名称指的是类,这个类定义中括号的内容是空的. 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板而实例是根据类创建出来的一个个具体 ...

  6. python基础——类定义(转)

    一.类定义: class <类名>: <语句> 类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性.如果直接使用类名修改其属性,那么将直接影响到已经实例 ...

  7. python基础-类的起源

    Python中一切事物都是对象. class Foo(object): def __init__(self,name): self.name = name f = Foo("alex&quo ...

  8. python基础-类的反射

    1)反射是通过字符串方式映射内存中的对象. python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr, 改四个函数分别用于对对象内部执行:检查是 ...

  9. python基础-类的继承

    继承:承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”.“父类. 继承的过程,就是从一般到特殊的过程.要实现继承,可以通过“继承”(Inheritance)和“组合”(Compositio ...

  10. Python 基础 类的继承

    如果寂静定义了Person类,需要定义新的Student 和Teacher 类时 可以直接从Person 中继承 class Person(Object): def __init__(self,nam ...

随机推荐

  1. javascript 中的location.pathname

    1 location.pathname; 这在之前我没怎么注意过,所以研究研究.location.pathname:返回URL的域名(域名IP)后的部分.例如 http://www.joymood.c ...

  2. MIFARE系列6《射频卡与读写器的通信》

    1. ATR(Answer to request) 读写器呼叫磁场内的卡片.卡片对呼叫做出应答. 对刚进入磁场得到电复位处于休闲状态的卡片,卡请求(REQA,0x26):对于已进行过读写操作并进入休眠 ...

  3. Android 2.3.5源码 更新至android 4.4,能够下载,度娘网盘

    Android 4.4源代码下载(linux合并) ==============================切割线结束========================= 旧版本号的能够使用115, ...

  4. 【百度地图API】暑假放假回老家——城市切换功能

    原文:[百度地图API]暑假放假回老家--城市切换功能 任务描述: 酸奶小妹放寒假啦,要从北京呼啦一下飞回重庆呢.现在百度地图API上不能直接切换城市,怎么办呢? 如何实现: 利用API先搜索到要去城 ...

  5. 使用SignalR打造消息总线

    使用SignalR为FineUI/Webform打造消息总线 第一次写博客,语言组织能力不好,请大家多多包涵! 效果图如下: 图片的右下角即为SignalR消息总线的消息框. 一.建立SignalR服 ...

  6. 换行符以及for循环的优化

    string str = ""; for (int i = 0; i < _errlistCusEmailInfo.Count; i++)                   ...

  7. MVC验证05-自定义验证规则、验证2个属性值不等

    原文:MVC验证05-自定义验证规则.验证2个属性值不等 本文体验2个属性值不等.即当一个属性输入值,另外一个属性输入的值不能和第一个属性值相等.相关文章包括: MVC验证01-基础.远程验证   M ...

  8. js+css3动态时钟-------Day66

    昨天,有一天招,宽带到底没装上.相当恼火,不过包了一天租新房,有很多想法下来,其中,率先实现了--动态时钟(它已上载的资源,一些粗略的全貌.汗...) 这里记录.这个看似简单的功能,以达到良好的,我在 ...

  9. 一个简单的创建dom的函数

    var  regName = /^(div|a|p|ul|li|input|select|document|body|iframe)$/;function createDom(name, obj) { ...

  10. YUV格式转换RGB(基于opencv)

    在编写代码将需要处理YUV格从每个视频帧中提取,然后将其保存为图片.有两种常见的方法在线,第一种是通过opencv自带cvCvtColor,可是这样的方法有bug.得到的图片会泛白.另外一种方法是公式 ...