Python是一门动态的语言
1、什么是动态语言
动态编程语言是高级程序设计语言的一个类别,他是一类在运行时可以改变其结构的语言:例如新的函数、对象、甚至代码可以被改进,已有的函数可以被删除或者是其他的结构上的变化。动态语言有:javascript、php、Ruby、Python等都是动态语言。
2、运行过程中给对象绑定(添加)属性
In [1]: class Person(object):
...: def __init__(self, new_name):
...: self.name = new_name
...:
In [2]: wang = Person("老王")
上面的代码中,我们定义了一个Person类,在类中有一个初始属性name,如果我们想添加age属性呢?
In [3]: wang.age = 18
In [4]: print(wang.name)
老王
In [5]: print(wang.age)
18
要给实例对象添加实例属性,可以直接对象名.属性 = 值
3、运行的过程中给类绑定(添加)属性
上面我们在运行过程中给实例对象添加了属性,那么我们再创建一个实例对象,能不能直接去调用age属性呢?
In [6]: li = Person("老李")
In [7]: li.age
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-7-683a5751e9b0> in <module>()
----> 1 li.age
AttributeError: 'Person' object has no attribute 'age'
我们发现在实例对象li中没有age这个属性,我么想给所有的Person的实例都加上age属性怎么办?答案就是直接给Person添加属性:
In [8]: Person.age = 0
In [9]: li = Person("老李")
In [10]: li.age
Out[10]: 0
4、运行过程中给类添加方法
首先我们定义一个函数:
def print_msg(self):
print("姓名:%s,年龄:%d" % (self.name, self.age))
上面我们直接给对象绑定属性,直接实例对象.属性 = 值
,那给实例对象添加方法呢?可不可以直接实例对象.方法名 = 方法名
呢?
wang.print_mag = print_msg
# 会直接产生异常 AttributeError: 'Person' object has no attribute 'print_msg'
# 是因为在调print_msg方法的时候,self并没有参数
那么我们怎么做才能添加呢?
import types
wang.print_msg = types.MethodType(print_msg, wang)
5、添加类方法
@classmethod
def p_class(cls):
cls.num = 100
# 动态添加类方法
Person.p_class = p_class
Person.p_class()
print(Person.num)
6、添加静态方法
@staticmethod
def run():
print("-----------run----------")
# 动态添加静态方法
Person.run = run
li.run()
7、__slots__
动态语言:可以再运行过程中,修改代码
静态语言:编译时已经确定好代码,运行过程中不能修改
如果我们想要限制实例的属性,怎么办?
比如,只允许对Person添加name、age、sex属性。
在Python中为了达到限制的目的,Python是允许在定义class的时候,定义一个特殊的__slots__
,来限制class实例能添加的属性
In [12]: class Person(object):
....: __slots__ = ("name", "age", "sex")
....:
In [13]: p = Person()
In [14]: p.name = "老王"
In [15]: p.age = 18
In [16]: p.sex = "男"
In [17]: p.address = "隔壁"
<hr />
AttributeError Traceback (most recent call last)
<ipython-input-17-c00075f138fc> in <module>()
----> 1 p.address = "隔壁"
AttributeError: 'Person' object has no attribute 'address'
注意点:
- 使用
slots
要注意,slots
定义的属性仅对当前类实例起作用,对继承的子类是不起作用的