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. 了解你的家公家IP

          我们总是在不在家的时候,须要訪问我们的电脑或设备,因为大多数人拥有来自ISP的动态IP,我们能够做一个小型设备来给我们的Android手机发送一个简单的通知,这样我们就能够总有IP用了,有 ...

  2. CSharp设计模式读书笔记(8):桥接模式(学习难度:★★★☆☆,使用频率:★★★☆☆)

    桥接模式(Bridge Pattern): 将抽象部分与它的实现部分分离,使它们都可以独立地变化.它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模 ...

  3. Oracle 11g 环境,使用utl_smtp创建一个存储过程来发送邮件

    太多的在线电子邮件存储过程.我不转发,弄个作为一个简单的例子演示. create or replace procedure Send_mail(mail_body varchar2) is smtp_ ...

  4. ASP.NET MVC性能优化工具 MiniProfiler

    ASP.NET MVC性能优化工具 MiniProfiler 2014年04月19日 ⁄ ASP.NET ⁄ 共 1159字 ⁄ 字号 小 中 大 ⁄ 暂无评论 ⁄ 阅读 325 views 次 MV ...

  5. 网上收集的WebBrowser的Cookie操作

    原文:网上收集的WebBrowser的Cookie操作 1.WebBrowser设置Cookie Code highlighting produced by Actipro CodeHighlight ...

  6. STL容器存储的内容动态分配情况下的内存管理

    主要分两种情况:存储的内容是指针:存储的内容是实际对象. 看以下两段代码, typedef pair<VirObjTYPE, std::list<CheckID>*> VirO ...

  7. 阅读安卓在线(Android)系统源代码

    http://grepcode.com/project/repository.grepcode.com/java/ext/com.google.android/android/ 版权声明:本文博客原创 ...

  8. 退出手机QQ依旧显示在线

    老婆说明明看到你手机QQ在线,怎么发信息不回复?这让我非常是冤枉,我明明退出了啊! 晚上宝宝睡觉后,我们一起来研究,发现了当中的秘密,原来仅仅要选择了"退出后仍接受消息通知"这个选 ...

  9. C语言连接Oracle

    原文:C语言连接Oracle 最近在搞C语言连接Oracle.DB2数据库,现把C连接Oracle的文章总结下: 用C语言连接ORACLE数据库.有两个思路和目的 思路一)本地环境:UBUNTU 7. ...

  10. HDU 3094 A tree game 树删边游戏

    叶节点SG值至0 非叶节点SG值至于它的所有子节点SG值添加1 XOR和后 #include <cstdio> #include <cstring> #include < ...