Please enable Javascript to view the contents

Python 的类函数方法

 ·  ☕ 4 分钟

1. 函数方法

函数是组织好的,可重复使用的,用来实现单一或相关联功能的代码片段。函数能提高应用的模块性,代码的重复利用率。Python 提供了许多内建函数,比如 print()、str()。同时,Python 也允许用户创建函数,这被叫做自定义函数。

Python 使用关键字 def 定义一个函数,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用 return 语句返回。在 Python 类中定义的方法,称之为类函数方法。看个例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# coding:utf-8
class A(object):
    def instance_method(self):
        print("类 {} 的实例方法".format(A.__name__))
        
    @staticmethod
    def static_method():
        print("静态方法")

    @classmethod
    def class_method(cls):
        print("类方法")
a = A()
a.instance_method()
A.static_method()
a.class_method()
A.class_method()
类 A 的实例方法
静态方法
类方法
类方法

上面具有函数名的函数,称之为命名函数。Python 也支持匿名函数,例如,lambda x: x * x。无论是命名函数,还是匿名函数,都是语句和表达式的集合。Python 函数和字符串、数字等一样,都是对象,拥有自己的一些属性,通过内置函数能查看这些属性。

1
dir(a.instance_method)

2. 函数参数

2.1 fun(a,b,c)

直接将实参赋予形参,根据位置做匹配,即严格要求实参的数量与行参的数量位置相等,比较一般,大多数语言常用这种方式

2.2 fun(a=1, b=2, c=3)

根据键值对的形式做实参与行参的匹配,通过这种式就可以忽略参数的位置关系,直接根据关键字来进行赋值,同时这种传参方式还有个好处就是可以在调用函数的时候,不要求参数数量上的相等,即可以 fun(3,4) 来调用函数,这里关键就是前面的 3,4 覆盖了原来 a、b 两个行参的值,但 c 还是不变采用原来的默认值 3,这种模式相较上面更加灵活,不仅可以通过 fun(c=5, a=2, b=7) 来打乱行参的位置,而且可以在但没有对应行参传递的时候常用定义函数时的默认值。

2.3 fun(*args)

这传参方式是可以传入任意个参数,这些若干参数都被放到了 tuple 元组中赋值给行参 args,之后要在函数中使用这些行参,直接操作 args 这个 tuple 元组就可以了,这样的好处是在参数的数量上没有了限制,但是因为是 tuple,其本身还是有次序的,这就仍然存在一定的束缚,在对参数操作上也会有一些不便

2.4 fun(**kargs)

最为灵活,其是以键值对字典的形式向函数传参,含有第二种位置的灵活的同时具有第三种方式的数量上的无限制。

2.5 混合传参与实例

fun(arg1, arg2, *args , **kargs),但四种方式混用时要遵守:

  • *args 须在 arg=value 之后
  • **kargs 须在 *args 之后
  • 赋值过程为,按顺序把传给实参赋值给对应的行参,args = value 形式的实参赋值给行参,将多余出的实参打包组成一个tuple 传递给 *args,将多余的 key=value 形式的实参打包正一个 dicrionary 传递给 **kargs。
1
2
3
4
5
def arg_test(arg1, arg2, *args , **kargs):
    print(arg1)
    print(arg2)
    print(args)
    print(kargs)
1
arg_test(1,2)    
1
2
()
{}
1
arg_test(1,2,3)
1
2
(3,)
{}
1
arg_test(1,2,3, a=4)
1
2
(3,)
{'a': 4}  

3. 函数方法

Python 类中提供了三种方法,实例方法( instancemethod),静态方法(staticmethod) ,类方法(classmethod )。当然,在 Python 中也可以通过 abc 模块中的 @abc.abstractmethod 声明抽象方法

3.1 实例方法

定义时,第一个参数永远是 self。只能通过实例名.方法名调用,可以访问类属性、实例属性,类方法、实例方法、静态方法。

实例方法和实例紧密相关,主要是用于改变、获取实例的状态,操作实例使用。

使用场景:和实例对象相关的方法,比如,初始化、修改,获取实例对象属性等。

1
2
3
4
5
class Date(object):
    def __init__(self, day=0, month=0, year=0):
        self.day = day
        self.month = month
        self.year = year

3.2 静态方法

没有任何必选参数,使用装饰器 staticmethod 修饰。可以通过实例名.方法名,也可以类名.方法名调用。不能访问实例属性和实例方法。

静态方法不会访问 class 、object 本身 ,而仅仅只是一个函数。

使用场景:属于类的方法,但是不会用到任何关于类的信息,比如,数据校验,算法等

1
2
3
4
5
6
7
class Date(object):
    @staticmethod
    def is_date_valid(date_as_string):
        day, month, year = map(int, date_as_string.split('-'))
        return day <= 31 and month <= 12 and year <= 3999

is_date = Date.is_date_valid('11-09-2012')

3.3 类方法

定义时,第一个参数永远是 cls,使用装饰器 classmethod 修饰。可以通过实例名.方法名,也可以类名.方法名调用。
其不能访问实例属性、实例方法,支持从特定格式的初始数据来创建对象。

类方法不是绑定到实例对象,而是绑定到类。

使用场景:用于创建类实例的工厂方法可以使用类方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Date(object):
    def __init__(self, day=0, month=0, year=0):
        self.day = day
        self.month = month
        self.year = year
    @classmethod
    def from_string(cls, date_as_string):
        day, month, year = map(int, date_as_string.split('-'))
        date1 = cls(day, month, year)
        return date1 
 
date2 = Date.from_string('11-09-2012')

4. 参考


微信公众号
作者
微信公众号