Python34_动态添加属性和方法

2019-09-27  本文已影响0人  jxvl假装

动态语言的定义

动态编程语言 是 高级程序设计语言 的一个类别,是月类在运行是可以改变其结构的语言:例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。

静态语言:运行之前需要先编译,比如C语言,不允许在运行过程中进行修改

添加属性和方法

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def eat():
        print("正在吃")


def run(self):
    print("%s正在跑" % self.name)


laowang = Person("laowang", 90)
laowang.addr = "beijing"  # 给对象添加属性,只有这个对象有,其他的该类的实例并没有该属性
Person.num = 100  # 给类添加属性,所有的该类实例都有该属性
# ps:如果是动态添加了形如Person.__num = 100,此处是属性的名字就是__num,而不是说num是私有属性
print(laowang.num)
print(laowang.addr)

laowang.run = run
laowang.run(laowang)    # 如果不传参在程序报错,因为run属性是后来添加的,laowang.run()的时候并没有把laowang当作第一个参数,导致调用run方法的时候出现缺少参数的问题
p1 = Person("laoli",34)
p1.run()  #程序报错,因为run方法是laowang这个对象添加的,p1这个对象并没有该方法

如何解决以上run方法必须自己手动传参的问题:利用types模块中的MethodType()方法

import types
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
def run(self):
    print("%s正在跑" % self.name)


laowang = Person("laowang", 90)
laowang.run = types.MethodType(run,laowang) #第一个参数为函数,第二个参数为对象实例
laowang.run()

拓展:types.MethodType的作用

import types
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
def run(self):
    print("%s正在跑" % self.name)


laowang = Person("laowang", 90)
laowang.run = types.MethodType(run,laowang) #相当于在以后调用run方法时,将laowang当作第一个对象传进去。为什么前面需要laowang.run?即MethodType有一个返回值,以后是用这个返回值去调run,所以返回值的接受者是谁并不重要,比如下面用xxx接收后就可以用xxx()调用。
#ps:通常而言,传入的参数方法叫什么,对象的方法名(即接受者)就叫什么
laowang.run()

xxx = types.MethodType(run,laowang)
xxx()

对实例可以动态添加属性,则对类也可以动态添加属性

动态添加静态方法

class P:
    pass

def eat():
    print("---吃---")
p = P()

p.eat = eat
p.eat() #因为静态方法可以不需要参数,直接通过类名调用,所以使用此种方法添加属性,调用时不需要传参

动态添加类方法

class  P:
    x = 2
@classmethod
def run(cls):
    print("--class method %d---"%cls.x)
P.run = run
P.run()
上一篇 下一篇

猜你喜欢

热点阅读