Python学习笔记(二十三):在运行的时候动态添加属性和方法


动态语言和静态语言的区别:

静态语言:先编译,后运行;像 C、C++、Java 等;编译之后什么样,运行的时候就是什么样;并且静态语言的类中有哪些属性,以及哪些方法,在定义类的时候就已经指定好了,在使用类的时候不能修改;

动态语言:不需要编译,直接运行,并且可以在运行的过程修改代码,即可以为类以及对象动态添加属性或者方法;像 Python、javascript、php 等;

 

动态给对象添加属性:

# 定义一个类
class Person(object):
    # 初始化方法:为对象初始化两个属性
    def __init__(self, name, age):
        self.name = name
        self.age = age

# 实例化对象
jack = Person("jack", 22)

# 直接获取对象的属性
print(jack.name)
print(jack.age)

# 动态给对象添加属性
jack.addr = "浙江杭州"
print(jack.addr)

 

动态给类添加属性:

上面给对象添加的属性只在当前对象有用,如果创建一个新的对象就不能用了;

可以给类添加属性,累属性是所有对象都可以共享的;

# 定义一个类
class Person(object):
    # 初始化方法:为对象初始化两个属性
    def __init__(self, name, age):
        self.name = name
        self.age = age

# 动态给类添加属性
Person.addr = "浙江杭州"

# 实例化对象
jack = Person("jack", 22)
print(jack.name)
print(jack.age)
print(jack.addr)

lucy = Person("lucy", 18)
print(lucy.name)
print(lucy.age)
print(lucy.addr)    # 给类添加的属性是所有对象共享的

 

动态给对象添加方法:

# 导入 types 模块
import types

# 定义一个类
class Person(object):
    # 初始化方法
    def __init__(self, name, age):
        self.name = name
        self.age = age

    # 定义一个成员方法
    def eat(self):
        print("=== %s在吃饭 ===" %self.name)

# 定义一个普通方法(注意:接收一个 self 参数)
def sleep(self):
    print("=== %s在睡觉 ===" %self.name)

# 实例化对象
jack = Person("jack", 22);
# 直接通过对象调用成员方法
jack.eat()

# 动态给对象添加方法;
# types.MethodType(sleep, jack):参数1表示普通方法的引用,参数2表示实例对象;
# 该方法表示将 参数1 表示的方法添加到 参数2 表示的对象中;
jack.sleep = types.MethodType(sleep, jack)
jack.sleep()    # 调用新添加的对象方法

 

动态给类添加静态方法:

# 定义一个类
class Person(object):
    pass

# 定义一个静态方法(静态方法可以没有参数)
@staticmethod
def sleep():
    print("=== 睡觉 ===")

# 动态给类添加静态方法:
# 即为 Person 类添加一个属性 sleep,接收静态方法 sleep() 的引用
Person.sleep = sleep
Person.sleep()  # 调用类的静态方法

# 注意:静态方法只能添加给类,而不能添加给对象,下面的做法是错误的:
jack = Person("jack", 22)
jack.sleep = sleep  # 动态为对象添加静态方法:
jack.sleep()

 

动态给类添加类方法:

# 定义一个类
class Person(object):
    pass

# 定义一个类方法(类方法需要接收一个 cls 参数)
@classmethod
def sleep(cls):
    print("=== 睡觉 ===")

# 动态给类添加类方法:
# 即为 Person 类添加一个属性 sleep,接收类方法 sleep() 的引用
Person.sleep = sleep
Person.sleep()  # 调用类方法

# 注意:类方法也是只能添加给类,而不能添加给对象,下面的做法是错误的:
jack = Person("jack", 22)
jack.sleep = sleep  # 动态为对象添加类方法:
jack.sleep()

 

__slots__ 变量的用法:

在上面我们已经知道,动态语言可以在运行的过程中动态添加属性和方法,那如果我想限制只允许为对象添加 name 和 age 属性,应该怎么做呢?

为了达到限制的目的,python 允许在定义 class 的时候,定义一个特殊的 __slots__ 变量,来限制该 class 的实例能够添加的属性;

# 定义一个类
class Person(object):
    # 限制只能为 Person 实例添加 name 和 age 属性
    __slots__ = ("name", "age")

# 实例化对象
jack = Person()

# 只能为对象添加 name 和 age 属性
jack.name = "jack"
jack.age = 22

print(jack.name, jack.age)

# 如果为对象添加其他属性,就会报错
jack.addr = "浙江杭州"

你可能感兴趣的:(python学习笔记)