一.动态语言的定义
python是一类在执行时能够改变其结构的语言:比如新的函数、对象、甚至代码能够被引进,已有的函数能够被删除或是其它结构上的变化。动态语言眼下很具有活力。
>>> class Person():
def __init__(self, name = None, age = None):
self.name = name
self.age = age
>>> P = Person("The_Third_Wave", "24")
>>>
在这里,我们定义了1个类Person,在这个类里,定义了两个初始属性name和age。可是人还有性别啊。假设这个类不是你写的是不是你会尝试訪问性别这个属性呢?
>>> P.sexuality = "male"
>>> P.sexuality
'male'
>>>
这时候就发现问题了,我们定义的类里面没有sexuality这个属性啊!
怎么回事呢?这就是动态语言的魅力和坑!这里实际上就是动态给实例绑定属性!
我们再看下一个样例
>>> P1 = Person("Wave", "25")
>>> P1.sexuality
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
P1.sexuality
AttributeError: Person instance has no attribute 'sexuality'
>>>
我们尝试打印P1.sexuality,发现报错,P1没有sexuality这个属性。----
给P这个实例绑定属性对P1这个实例不起作用!那我们要给全部的Person的实例加上
sexuality属性怎么办呢?
答案就是直接给Person绑定属性
>>>> Person.sexuality = None
>>> P1 = Person("Wave", "25")
>>> print P1.sexuality
None
>>>
三.添加方法
那么function呢?怎么绑定?
>>> class Person():
def __init__(self, name = None, age = None):
self.name = name
self.age = age
def eat(self):
print "eat food"
>>> def run(self, speed):
print "Keeping moving, the speed is %s km/h" %speed
>>> P = Person("The_Third_Wave", "24")
>>>
KeyboardInterrupt
>>> P.run()
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
P.run()
AttributeError: Person instance has no attribute 'run'
>>> P.eat()
eat food
>>> import types
>>> Person.run = types.MethodType(run, None, Person)
>>> P.run(180)
Keeping moving, the speed is 180 km/h
>>>
静态方法添加,用类直接加
@staticmethod
def test():
print("-------static method-----")
Person.test = test
Pserson.test()
-------static method-----
添加类方法
#classmethoddef printNum():
print("-----class method-----")
Person.printNum = printNum
Persong.printNum()
四.删除属性
>>> P.name
'The_Third_Wave'
>>> P.sex
Traceback (most recent call last):
File "<pyshell#32>", line 1, in <module>
P.sex
AttributeError: Person instance has no attribute 'sex'
>>> setattr(P, "sex", "male") # 増
>>> P.sex
'male'
>>> delattr(P, "name") # 删
>>> P.name
Traceback (most recent call last):
File "<pyshell#36>", line 1, in <module>
P.name
AttributeError: Person instance has no attribute 'name'
>>>
五.删除方法
>>> class Person():
def __init__(self, name = None, age = None):
self.name = name
self.age = age
def eat(self):
print "eat food"
>>> P = Person("The_Third_Wave", "24")
>>> P.eat()
eat food
>>> P.run()
Traceback (most recent call last):
File "<pyshell#41>", line 1, in <module>
P.run()
AttributeError: Person instance has no attribute 'run'
>>> def run(self, speed):
print "Keeping moving, the speed is %s" %speed
>>> setattr(P, "run", run)
>>> P.run(360)
Traceback (most recent call last):
File "<pyshell#45>", line 1, in <module>
P.run(360)
TypeError: run() takes exactly 2 arguments (1 given)
>>> P.run(1, 360)
Keeping moving, the speed is 360
>>>
>>> delattr(P, "run")
>>> P.run()
Traceback (most recent call last):
File "<pyshell#48>", line 1, in <module>
P.run()
AttributeError: Person instance has no attribute 'run'
>>>
删除
>>> delattr(P, "run")
>>> P.run()
Traceback (most recent call last):
File "<pyshell#48>", line 1, in <module>
P.run()
AttributeError: Person instance has no attribute 'run'
>>>
通过以上样例能够得出一个结论:相对于动态语言。静态语言具有严谨性!
所以,玩动态语言的时候。小心动态的坑!
六.__slots__
规定类只能添加指定的属性,不能添加额外的属性
__slots_ = ("name","age") #只能添加name和 age, 不能添加其他属性
七. types.MethodType 的作用(函数指针)
因为方法也是一个属性,所以,它也可以动态地添加到实例上,只是需要用 types.MethodType() 把一个函数变
import types
def fn_get_grade(self):
if self.score >= 80:
return 'A'
if self.score >= 60:
return 'B'
return 'C'
class Person(object):
def __init__(self, name, score):
self.name = name
下面我们将fn_get_grade()方法添加到实例上:
>>> p1 = Person('Bob', 90)
>>> p1.get_grade = types.MethodType(fn_get_grade, p1, Person)
>>> print p1.get_grade()
A
>>> p2 = Person('Alice', 65)
>>> print p2.get_grade()
# ERROR: AttributeError: 'Person' object has no attribute 'get_grade'
因p2实例没有绑定get_grade方法,所以出现错误。