设为首页 加入收藏

TOP

24.python中类的方法(一)
2017-09-30 16:21:51 】 浏览:8693
Tags:24.python 方法

  类中的方法,其实就是类中的函数,可以分为:实例方法,类方法,静态方法。方法和字段一样,也是属于类的属性,所以也具有运行中修改的特效, 但一般不推荐这样做。

  我在类的基本语法中,介绍了构造器方法:__init__ 、__new__;解构器方法:__del__;

  注意,这里虽然是以两个下划线(__)开头,但同时以两个下划线(__)结尾,这里表明其是一个‘魔法方法’,关于类中的魔法方法,将起一篇进行说明。

  但是,如果单纯只以两个下划线开始,则依然是私有化的意思,看代码示例:

class Test(object):

    def __scolia__(self):   # 一个类似魔术方法,并不是私有化
        return 'scolia'

    def __good(self):   # 私有方法
        return 'good'

a = Test()
print a.__scolia__()   # 魔法方法可以在直接访问
print a.__good()    # 私有方法不能直接访问

 

  同样的,和字段私有化一样,我们也可能同特殊手段进行强制访问:

print a._Test__good()  # 强制访问

 

  当然,私有方法也可以在类的内部访问,和私有字段一样。

  所以说,属性的私有化都是对访问入口进行混淆,同样的,也不建议强制访问私有属性。

  也许这里的‘魔法方法’看起来并不‘魔法’,详情将以后解释。


实例方法:

  在 __init__ 构造器中,提起过其是一个实例方法,实例方法的特点就是:

  1.方法的第一个参数必须是 self,当然这是约定俗成的写法,你可以将 self 换成 abc 之类的,但是为了别的程序员能看得懂,还是统一用 self 吧。这里的 self 代表实例本身,也就是说如果我实例化时使用的是: a = Test() ,那么 self 就代表 a 这个实例,我们可以在很多构造器中看到类似 self.scolia = 'good' 的写法,其实这个写法和在类外面 a.scolia = 'good' 效果一样,是为了添加属性,只不过 __init__ 方法是实例化时自动调用的函数,所以适合进行初始属性的创建。

  2.实例方法在调用的时候,self 是自动传递的,所以不需要我们再处理。

  3.实例方法一般要有实例才能调用,当然也有特殊的调用方法。

代码示例:

class Test(object):

    def __init__(self, a, b):   # 构造器在实例创建时进行属性的初始化
        self.a = int(a)
        self.b = int(b)

    def abc(self, c):  # 实例方法
        print self.a + self.b + int(c)  # 因为self是自动传递的,所以我们可以在实例方法中调用实例的属性

a = Test(123, 321)  # 我们只要为 a 和 b 传参就行了
a.abc(666)  # 同样的,只要为 c 传参

 

  这里,将引入一个绑定 (binding) 的概念,其主要和方法的调用有关。

  首先,我们知道方法是类的属性,而不是实例的属性,在上篇博文类的属性和实例的属性中我们也讨论过这个问题。

  其次,方法只有在其所属的类拥有实例时,才能被调用。当一个类存在实例后,方法才被认为是绑定到这个实例。没有实例的时候,方法是未绑定的。

  最后,任何一个方法定义的第一个参数都是变量 self ,它表示调用此方法的实例对象。

  很明显这里的绑定针对的是实例方法。因为如果没有实例的话,self 就无法传递,这将导致参数的不足,当然就无法调用了。

  但是,我们可以自己传递 self 来调用未绑定的方法。调用未绑定的方法通常是在我们继承了一个父类后, 我们覆盖了父类中的某个方法,但是为了实现代码重用,我们又想在子类中调用父类的方法。单纯的复制父类中的代码明显不是一个好选择, 除了浪费系统资源之外,还有可能在复制的时候出错,而且以后修改父类的代码之后,还要修改相应子类中的代码,实在太低效,这个时候就是调用未绑定方法的场景。

代码示例:

class abc(object):
    def __init__(self, a):
        self.a = -int(a)

class Test(abc):
    def __init__(self, a, b):
        abc.__init__(self, a)   # 调用父类的构造器,并手动传递 self
        self.b = b

    def fangfa(self):
        print self.a + self.b   # 属性 a 由父类的构造器创建,b 由子类构造器创建

a = Test(123, 321)  # 我们只创建了子类的实例,而没有创建父类的实例
a.fangfa()

 

  本来我们没有创建父类的示例,是无法调用父类的实例方法的,但是我们手动传递了实例方法需要的 self 参数,就可以实现调用了。

  这里的顺序是,我们创建了 Test 的实例,其 self 是自动传递的,故 Test 的构造方法 __init__(self, a, b) 中 self 就代表实例 a,而我们又调用了父类的 abc.__init__(self, a) 这里的 self 就是子类的实例 a ,参数 a 就是我们传的 123,而父类中 self.a = -int(a) ;最后我们可在子类的方法中调用 self.a 这个属性。

 


 

类方法:

  类方法其实和实例方法类似,不过其第一个参数一般是 cls (约定俗成)而不是 self。但是,如果我们直接将 self 换成 cls 来创建类方法是不对的,因为实例方法的首个参数也是任意的,只是统一使用 self 。python的解释器并没有说看见第一个参数是 cls 就知道这个是类方法,它还是将其当作是实例方法来对待,所以我们需要通过内建函数: classmethod() 来创建类方法。

代码示例:

class Test(object):

    def abc(cls):
        print cls.__name__  # 打印类名

    abc = classmethod(abc)  # 通过普通的函数传参的方式创建类方法

a = Test()  
Test.abc()  # 类能调用
a.abc()     # 实例也能调用

 

  当然,有同学在看到这段代码的时候想到了装饰器,实际上我们也可以使用装饰器的方法来创建类方法:

class Test(object):
    @classmethod
    def abc(cls):
        print cls.__name__  # 打印类名

 

  结果也是一样的,具体选择看个人喜好。

  注意,因为使用了  classmethod()函数,其第一个参数 cls 是固定传递的,而且是代表当前的类。并没有实例方法中非绑定方法的调用形式。

 


 

静态方法:

  静态方法其实就是类中的一个普通函数,它并没有默认传递的参数,在创建静态方法的时候,需要用到内置函数: staticmethod()

代码示例:

class Test(object):

    def abc():
        print 'abc'
        
    abc = staticmethod(abc)

    @staticmethod
    def xyz(a, b):
        print a + b

Test.abc()  # 类调用
Te
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Python for Infomatics 第14章 数.. 下一篇Python文件处理之文件指针(四)

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目