专栏首页Python小屋详解Python类定义中的各种方法

详解Python类定义中的各种方法

首先应该明确,在面向对象程序设计中,函数方法这两个概念是有本质区别的。方法一般指与特定实例绑定的函数,通过对象调用方法时,对象本身将被作为第一个参数传递过去,普通函数并不具备这个特点。

>>> class Demo:

pass

>>> t = Demo()

>>> def test(self, v):

self.value = v

>>> t.test = test #动态增加普通函数

>>> t.test

<function test at 0x00000000034B7EA0>

>>> t.test(t, 3)

>>> print(t.value)

3

>>> import types

>>> t.test = types.MethodType(test, t) #动态增加绑定的方法

>>> t.test

<bound method test of <__main__.Demo object at 0x000000000074F9E8>>

>>> t.test(5)

>>> print(t.value)

5

Python类的成员方法常用的类型有公有方法私有方法静态方法类方法抽象方法等等。公有方法、私有方法和抽象方法一般是指属于对象的实例方法,私有方法的名字以两个下划线“__”开始,而抽象方法一般定义在抽象类中并且要求派生类必须重新实现。每个对象都有自己的公有方法和私有方法,在这两类方法中都可以访问属于类和对象的成员。公有方法通过对象名直接调用,私有方法不能通过对象名直接调用,只能在其他实例方法中通过前缀self进行调用或在外部通过特殊的形式来调用。另外,Python中的类还支持大量的特殊方法,这些方法的两侧各有两个下划线“__”,往往与某个运算符和内置函数相对应。

所有实例方法(包括公有方法、私有方法、抽象方法和某些特殊方法)都必须至少有一个名为self的参数,并且必须是方法的第一个形参(如果有多个形参的话),self参数代表对象自身。在类的实例方法中访问实例属性时需要以self为前缀,但在外部通过对象名调用对象方法时并不需要传递这个参数。如果在外部通过类名调用属于对象的公有方法,需要显式为该方法的self参数传递一个对象名,用来明确指定访问哪个对象的数据成员。

静态方法类方法都可以通过类名和对象名调用,但不能直接访问属于对象的成员,只能访问属于类的成员。另外,静态方法和类方法不属于任何实例,也不需要绑定到实例,也不依赖与实例的状态,与实例方法相比能够减少很多开销。一般以cls作为类方法的第一个参数表示该类自身,在调用类方法时不需要为该参数传递值,而静态方法则可以不接收任何参数。例如下面的代码所演示:

>>> class Root:

__total = 0

def __init__(self, v): #构造方法

self.__value = v

Root.__total += 1

def show(self): #普通实例方法

print('self.__value:', self.__value)

print('Root.__total:', Root.__total)

@classmethod #修饰器,声明类方法

def classShowTotal(cls): #类方法,以cls作为第一个参数的名字

print(cls.__total)

@staticmethod #修饰器,声明静态方法

def staticShowTotal(): #静态方法,可以没有参数

print(Root.__total)

>>> r = Root(3)

>>> r.classShowTotal() #通过对象来调用类方法

1

>>> r.staticShowTotal() #通过对象来调用静态方法

1

>>> rr = Root(5)

>>> Root.classShowTotal() #通过类名调用类方法

2

>>> Root.staticShowTotal() #通过类名调用静态方法

2

>>> Root.show() #试图通过类名直接调用实例方法,失败

Traceback (most recent call last):

File "<pyshell#9>", line 1, in <module>

Root.show()

TypeError: unbound method show() must be called with Root instance as first argument (got nothing instead)

>>> Root.show(r) #可以通过这种方法来调用方法并访问实例成员

self.__value: 3

Root.__total: 2

>>> r.show()

self.__value: 3

Root.__total: 2

抽象方法一般在抽象类中定义,并且要求在派生类中必须重新实现,否则不允许派生类创建实例。

import abc

class Foo(metaclass=abc.ABCMeta): #抽象类

def f1(self): #普通实例方法

print(123)

def f2(self): #普通实例方法

print(456)

@abc.abstractmethod #抽象方法

def f3(self):

raise Exception('You musr reimplement this method.')

class Bar(Foo):

def f3(self): #必须重新实现基类中的抽象方法

print(33333)

b = Bar()

b.f3()

本文分享自微信公众号 - Python小屋(Python_xiaowu),作者:董付国

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-10-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 对Python列表进行封装和二次开发实现自定义栈结构

    设计自定义栈类,模拟入栈、出栈、判断栈是否为空、是否已满以及改变栈大小等操作。 class Stack: #构造方法 def __init__(self, ...

    Python小屋屋主
  • Python实现带有阻塞和超时放弃功能的队列结构

    本文代码对Python列表进行封装并模拟了队列结构,入队时如果队列已满则阻塞当前线程,超时则放弃;出队时如果队列已空则阻塞当前线程,超时则放弃。 import ...

    Python小屋屋主
  • Python使用matplotlib绘制正多边形逼近圆周

    运行结果:用鼠标单击或拖动Slider组件并修改其值,单击按钮组件可以恢复Slider组件的默认值6。

    Python小屋屋主
  • 泰迪熊智能玩具泄露数百万音频信息和用户密码

    正打算给自家小孩买可联网玩具或智能玩具的家长请注意,你可能需要三思而后行了,这些诡异的玩具会给小朋友们带来一些潜在的隐私和数据安全风险。

    FB客服
  • 微信声音锁降临 以声识人设备不再遥远

      语音短信是微信的一大特色,方便了广大受众。语音命令是未来的一个趋势,搜索引擎支持语音搜索,谷歌眼镜可以语音开始拍照,现在微信创新性推出声音锁功能,只要读出相...

    ytkah
  • Yii2工作中的一些方法技巧

    假设我们当前页面的访问地址是:http://localhost/public/index...

    botkenni
  • C#项目代码规范

       小菜就是小菜,几个人搞出来的项目,让公司大牛稍微看了下,最后送出了惨不忍睹四个字。命名各种各样,五花八门,大写英文、小写英文、大写拼音、小写拼音、英文和拼...

    aehyok
  • IOS开发中滑动页面时NSTimer停止的问题

    王大锤
  • JavaScript设计模式之模板方法模式

    泡茶和泡咖啡,整个过程都是类似的。我们可以抽离其中的概念:泡东西=>煮水->收集浸泡材料->泡->等。

    一粒小麦
  • 智能云上手指南:语音合成 API 快速接入

    本文将为大家讲解如何上手智能云提供的智能语音识别服务。

    云加社区

扫码关注云+社区

领取腾讯云代金券