Python特性-运行时动态添加方法

  |  

摘要: Python 中在运行时动态添加方法

【对算法,数学,计算机感兴趣的同学,欢迎关注我哈,阅读更多原创文章】
我的网站:潮汐朝夕的生活实验室
我的公众号:算法题刷刷
我的知乎:潮汐朝夕
我的github:FennelDumplings
我的leetcode:FennelDumplings


编程语言分为动态语言和静态语言。静态语言是先编译后运行的,例如 C++、Java 都是静态语言。编译之后是什么样,运行的时候就是什么样了。类中有哪些属性和方法,在定义类的时候就已经确定了,在使用类的时候不能修改。

动态语言不需要编译,直接运行,并且可以在运行的过程修改代码,可以为类和对象动态添加属性或者方法,Python 就是动态语言。

本文我们就来学习一下在 Python 中如何在运行时给类添加属性和方法。

假设我们有一个 Person 类,有 name 和 age 两个属性,以及 show_age 一个方法。

1
2
3
4
5
6
7
class Person:
def __init__(self, name, age):
self.name = name
self.age = age

def show_age(self):
print("age is {}".format(self.age))

现在我们实例化一个对象,并访问对象的属性

1
2
3
4
5
# 实例化对象
person = Person("Fennel", 35)
# 访问对象属性
print("person.name: {}".format(person.name))
print("person.age: {}".format(person.age))

下面我们通过类 Person 及其对象 person 来看一下如何在运行时添加属性和方法

1. 给对象添加属性

给对象 person 增加一个 city 属性,这个需求比较简单,直接通过像下面这样赋值的方式就可以给对象添加属性。

1
2
3
# 给对象 person 增加 city 属性
person.city = "Beijing"
print("person.city: {}".format(person.city))

2. 给类添加属性

像上面那样给 person 对象添加 city 属性的方式,只能对当前对象有效。当创建新对象后,city 这个给 person 添加的属性就无效了。

此时可以给类添加属性,类属性是所有对象都可以共享的。写法也比较简单,就是把对象名 (person) 改成类名 (Person) 即可。

1
2
3
4
5
# 给类 Person 添加类属性 city
Person.city = "Shanghai"
print("person.city: {}".format(person.city)) # 新加的类属性不会覆盖现有对象的属性
person2 = Person("chaoxi", 41)
print("person2.city: {}".format(person2.city)) # 新加的类属性对新实例是有效的

3. 给对象添加方法

对象 person 已有一个 show_age 方法,给对象 person 添加一个普通方法 show_name。

需要用到标准库 types 模块的 MethodType。首先定义一个接收 self 参数的函数 show_name。然后调用 types.MethodType(show_name, person),第一个参数是普通方法的引用,第二个参数是实例对象。

1
2
3
4
5
6
# 给对象添加方法
import types
def show_name(self):
print("name is {}".format(self.name))
person.show_name = types.MethodType(show_name, person)
person.show_name()

4. 给类添加静态方法

下面我们给 Person 类添加一个静态方法 sleeping。

首先定义一个静态方法 sleeping (静态方法可以没有参数),然后给 Person 类添加这个静态方法,也就是为 Person 类添加一个属性 sleeping,接收静态方法 sleeping() 的引用

注意静态方法只能添加给类,不能添加给对象。

1
2
3
4
5
@staticmethod
def sleeping():
print("sleeping")
Person.sleeping = sleeping
Person.sleeping()

5. 给类添加静态方法

下面我们给 Person 类添加一个类方法 sleeping。

首先定义一个类方法(类方法需要接收一个 cls 参数),然后给 Person 类添加这个类方法,也就是为 Person 类添加一个属性 eating,接收类方法 eating 的引用。

注意类方法也是只能添加给类,不能添加给对象。

1
2
3
4
5
6
# 给类添加类方法
@classmethod
def eating(cls):
print("eating")
Person.eating = eating
Person.eating()

Share