Python 的动态特性

Python 是一种动态语言,拥有动态语言的相关特性…

动态编程语言高级程序设计语言 的一个类别,在计算机科学领域已被广泛应用。它是一类在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。动态语言目前非常具有活力。例如 JavaScript 便是一个动态语言,除此之外如 PHP 、Ruby 、Python 等也都属于动态语言,而 C、C++ 等语言则不属于动态语言。

  • 运行的过程中给实例绑定属性
  • 运行的过程中给类绑定属性
  • 运行的过程中给实例绑定方法
  • 运行的过程中给类绑定方法
  • 运行的过程中删除属性、方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Person(object):
def __init__(self, name):
self.name = name

xiaoli = Person('小里')
print(xiaoli.name)

# 运行的过程中给对象绑定属性
xiaoli.age = 12
print(xiaoli.age)
# age 属性只属于 xiaoli,Person中并没有
print(dir(Person))
print(dir(xiaoli))

# 运行的过程中给类绑定属性
Person.address = None
print(dir(Person))

xiaoni = Person("小妮")
xiaoni.address = "江苏"
print(xiaoni.address)

# 运行的过程中给实例绑定方法
def run(self):
print("%s is running" %self.name)

import types
# 不能直接使用 xiaoli.run = run
xiaoli.run = types.MethodType(run, xiaoli)
print(dir(Person))
print(dir(xiaoli))

xiaoli.run()

# 运行的过程中给类绑定方法
Person.run = run
print(dir(Person))
print(dir(xiaoli))
xiaoni.run()

# 运行中删除类的方法
delattr(Person, "run")
# del Person.run
del Person.address
print(dir(Person))

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ python testDynamic.py
小里
12
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'address']
江苏
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'address']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'address', 'age', 'name', 'run']
小里 is running
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'address', 'run']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'address', 'age', 'name', 'run']
小妮 is running
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
  • 删除的方法:
    • del 对象.属性名
    • delattr(对象, “属性名”)

__slots__

现在我们终于明白了,动态语言与静态语言的不同:

  • 动态语言:可以在运行的过程中,修改代码
  • 静态语言:编译时已经确定好代码,运行过程中不能修改

如果我们想要限制实例的属性怎么办?比如,只允许对 Person 实例添加 name 和 age 属性。为了达到限制的目的,Python 允许在定义 class 的时候,定义一个特殊的 __slots__ 变量,来限制该 class 实例能添加的属性。

1
2
3
4
5
6
7
class Person(object):
__slots__ = ("name" ,"age")

xi = Person()
xi.name = "xixi"
print(xi.name)
xi.address = "China"

运行结果:

1
2
3
4
5
6
$ python testSlots.py
xixi
Traceback (most recent call last):
File "testSlots.py", line 7, in <module>
xi.address = "China"
AttributeError: 'Person' object has no attribute 'address'

使用 __slots__ 要注意,__slots__ 定义的属性仅对当前类实例起作用,对继承的子类是不起作用的

1
2
3
4
5
class Man(Person):
pass
mi = Man()
mi.address = "JS"
print(mi.address)

运行结果:

1
2
3
$ python testSlots.py
xixi
JS
hoxis wechat
一个脱离了高级趣味的程序员,关注回复1024有惊喜~
赞赏一杯咖啡
0%