深入理解Python的动态语言特性与多态

Python是门动态语言

  • 动态体现在能够在程序运行过程中对变量类型进行修改。例如下面这个例子:
a = 100
print(a)

def test():
    print("---test---")

a = test
a()
  • 运行结果如下。原来a指向一个整形数据类型,在程序运行至后面的代码,a又指向了一个函数体,这就是动态的体现。
100
---test---
  • 动态的另外一个体现就是能够在程序运行过程中向定义好的类中添加实例属性、类属性、类方法和静态方法。下面用代码进行展示:
class People(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

laowang = People("laowang", 18)
print(laowang.name)
print(laowang.age)
laowang.sex = "male"#动态添加实例属性的方法
print(laowang.sex)
laozhang = People("laozhang",20)
print(laozhang.name)
print(laozhang.age)
#print(laozhang.sex)#这句话执行会报错,因为添加的实例属性sex只存在于laowang这个实例中
#而类属性则是各实例间共享的
People.planet = "earth"#动态添加类属性的方法
print(laowang.planet)
print(laozhang.planet)

@classmethod
def wear(cls):
    print("---classmethod ware---")

@staticmethod
def walk():
    print("---staticmethod walk---")

People.wear = wear#动态添加类方法的方法
People.walk = walk#动态添加实例方法的方法
#从添加的方法可以看出实例属性属于实例本身,添加时使用实例名;而类方法、类属性、静态方法则属于类本身,添加时使用类名。
laowang.wear()
laowang.walk()
  • 以上代码输出结果如下:
laowang
18
male
laozhang
20
earth
earth
---classmethod ware---
---staticmethod walk---
  • 除了能够动态地添加实例属性、类属性、类方法和静态方法,当然还能够添加实例方法,只是添加的方式有所不同。下面同样使用代码展示:
import types#需要导入该模块

class People(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def eat(self):
        print("---%s is eating---"%self.name)

def run(self):
    print("---%s is running---"%self.name)

laowang = People("laowang", 18)
laowang.eat()
laowang.run = types.MethodType(run, laowang)#动态添加实例方法的方法
laowang.run()
laozhang = People("laozhang", 20)
laozhang.eat()
#laozhang.run()#这句话执行会报错,因为添加的实例方法run()只存在于laowang这个实例中
  • 以上代码的输出结果如下:
---laowang is eating---
---laowang is running---
---laozhang is eating---

__slots__的作用

  • 上面我们讲了Python是一门动态语言,在定义好的类中我们能够随意的添加各种实例属性和方法,这虽然相对于静态语言有很大的优势,但有时也有弊端。当我们不愿意他人随意添加实例属性及方法时,就需要用到__slots__
  • 下面用代码进行展示:
import types
class People(object):
    __slots__ = ("name","age")
    def __init__(self, name, age):
        self.name = name
        self.age = age

def run(self):
    print("---%s is running---"%self.name)

laowang = People("laowang", 18)
print(laowang.name)
# laowang.sex = "male"#会添加失败,因为"sex"不在变量__slots__中
People.planet = "earth"#添加成功,因为__slots__只能限定实例的属性和方法,对类不起作用
print(laowang.planet)
# laowang.run = types.MethodType(run, laowang)#会添加失败,因为"run"不在变量__slots__中

Python多态的体现

  • 下面用代码来说明Python的多态,这也是在c++中定义的多态性:
class Father(object):
    def introduce(self):
        print("---hello, I'm the father---")

class Son(object):
    def introduce(self):
        print("---hello, I'm the son---")

def introduce_yourself(instance):
    instance.introduce()#这里并不确定是调用哪个类的introduce()方法,所以称为多态
    #在c++中的做法是在接收参数instance前面加上父类的名字
    #多态的实现必须是在子类中重写父类的方法

human1 = Father()
human2 = Son()
introduce_yourself(human1)
introduce_yourself(human2)
  • 输出结果如下:
---hello, I'm the father---
---hello, I'm the son---

猜你喜欢

转载自blog.csdn.net/gaishi_hero/article/details/81838829