Python详解如何动态给对象增加属性和方法
本文深入解析Python作为动态语言的特性,详细演示如何在运行时为对象实例动态添加属性和方法,以及如何为整个类绑定属性和方法。通过具体代码示例,涵盖使用types模块绑定实例方法、类方法与静态方法,并介绍删除动态绑定的方式,帮助开发者掌握Python对象模型的灵活性。
Python动态绑定属性与方法概述
Python对象动态的增加属性和方法
此前我们已了解数据封装、继承和多态是面向对象程序设计的三大基础概念。
在Python中,面向对象编程还包含许多高级特性,能够支持实现非常强大的功能。
动态语言特性与实例属性绑定
Python属于动态语言,动态编程语言是高级程序设计语言的一个类别,在计算机科学领域应用广泛。这类语言允许在运行时改变其结构:例如可以引入新的函数、对象甚至代码,也可以删除已有函数或进行其他结构上的变更。
动态语言目前极具活力。例如,我们创建一个Person类,并在其中定义两个初始属性name和age。
# -*- coding: utf-8 -*-
class Person(object):
def __init__(self, name=None, age=None):
self.name = name
self.age = age接下来实例化一个Person对象,假设P对象代表张三,我们传入p对象的两个属性,即姓名和年龄。此时,p对象就像是我们自己,将姓名和年龄这些属性绑定在自身身上。
>>> p = Person('张三', 20)
接着,假设我们遇到一个问题:我不认识这个人,例如在一个人员系统中,我在茫茫人海中无意间看到了p对象,出于好奇或需要查询资料,我想查看他的性别信息。
>>> p.name 张三 >>> # 如果这里直接访问p.sex会报错,因为初始定义中没有性别信息 >>> p.sex = '男' >>> p.sex 男
此时发现问题:我们定义的类中并没有sex这个属性!这是怎么回事?这正是动态语言的魅力与潜在陷阱所在。这里实际上演示了动态给实例绑定属性的过程。
动态绑定类属性与实例差异
在程序运行过程中,我们可以给类绑定属性,请看下面的例子。
>>> p2 = Person('李四', 20) >>> p2.sex Traceback (most recent call last):4 ....... AttributeError: Person instance has no attribute 'sex' >>>
我们尝试打印p2.sex,发现报错,因为p2没有sex这个属性!这说明给p1实例绑定属性对p2实例不起作用。那么,如果我们要给所有的Person实例都加上sex属性,该怎么办?答案是可以直接给Person类绑定属性。
>>> Person.sex = None # 给类Person添加一个属性 >>> p2 = Person('李四', 20) >>> print(p.sex) # 如果p1这个实例对象中没有sex属性的话,那么就会访问它的类属性 None # 可以看到没有出现异常 >>>
动态绑定实例方法与类方法
我们直接给Person类绑定sex属性,重新实例化p2后,p2就拥有了sex属性!那么,如何绑定函数(方法)呢?
# -*- coding: utf-8 -*-
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print('吃食物')
# 单独定义一个方法
def test(self, work):
print('%s在%s' % (self.name, work))>>> P = Person("小明", 24) >>> p.eat() eat food >>> p.run() Traceback (most recent call last): ...... AttributeError: Person instance has no attribute 'run'
>>> import types >>> p.test = types.MethodType(test, p) >>> p.test('学习') 小明在学习
既然给类添加方法是通过 类名.方法名 = xxxx 的方式,
那么给对象添加一个方法也是类似的,即 对象.方法名 = xxxx。
请看完整代码,演示对类方法、实例方法及动态绑定的增加操作:
# -*- coding: utf-8 -*-
import types
class Person(object):
num = 0 # 类属性
def __init__(self, name, age):
self.name = name
self.age = age
# 定义一个函数
def eat(self, food):
print(self.name + '在吃' + food)
# 定义一个类方法
@classmethod
def cm(cls):
print('这是给Person类动态赋予一个类函数')
# 定义一个静态方法
@staticmethod
def sm():
print('这是给Person类动态赋予一个一个静态函数')
if __name__ == '__main__':
p = Person('张三', 33) # 创建对象
Person.address = '北京' # 类属性
# 1.可以给 对象p 动态的赋予一个对象属性
p.sex = '男' # 对象属性
# 2.可以给对象 p 动态赋予一个新的对象函数
p.eat = types.MethodType(eat, p)
print(p.eat('牛奶'))
# 3. 给Person类动态赋予一个类函数
Person.cm = cm
# 调用类方法
print(Person.cm())
# 4.给Person类动态赋予一个静态函数
Person.sm = sm
# 调用静态方法
print(Person.sm())
动态绑定属性的删除操作
既然有增加,自然也有删除。
以下是删除对象与属性的方法。
使用 del 对象.属性名
或使用 delattr(对象, “属性名”)。
动态语言灵活性与注意事项
我们知道,正常情况下,当我们定义了一个class并创建其实例后,我们可以给该实例绑定任何属性和方法,这体现了动态语言的灵活性。首先定义class:然后尝试给实例绑定一个属性,还可以绑定一个方法,但是一个实例的方法对另一个实例不起作用。
因此,如果需要让所有实例都能调用某个方法或属性,就需要给整个类绑定一个方法或属性。
需要注意的是,动态语言在运行后还能修改,但静态语言是不允许的,这可能导致代码严谨性不足。
到此这篇关于Python详解如何动态给对象增加属性和方法的文章就介绍到这了,更多相关Python动态增加属性方法内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









