为什么说Python是一门动态语言--Python的魅力,,


动态语言的定义:动态编程语言是高级程序设计语言的一个类别。在计算机科学领域已被广泛应用。它是一类在执行时能够改变其结构的语言:比如新的函数、对象、甚至代码能够被引进。已有的函数能够被删除或是其它结构上的变化。动态语言眼下很具有活力。众所周知的ECMAScript(JavaScript)便是一个动态语言,除此之外如PHP、Ruby、Python等也都属于动态语言,而C、C++等语言则不属于动态语言。

----来自维基百科

你是不是有过给class里面变量赋值却发现程序没达到自己预期结果的遭遇?是不是本来赋值给class.abc却赋给了class.abd?这事实上是动态语言惹的“祸”!【博主曾经玩的是java】我们先来试着玩一玩

>>> 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这个属性啊!

怎么回事呢?这就是动态语言的魅力和坑!

这里实际上就是动态给实例绑定属性!所以博主“当年”从java转python被“坑”(无知啊)过!我们再看下一个样例

>>> P1 = Person("Wave", "25")>>> P1.sexualityTraceback (most recent call last):  File "<pyshell#21>", line 1, in <module>    P1.sexualityAttributeError: Person instance has no attribute ‘sexuality‘>>> 
我们尝试打印P1.sexuality,发现报错,P1没有sexuality这个属性。----给P这个实例绑定属性对P1这个实例不起作用。

那我们要给全部的Person的实例加上sexuality属性怎么办呢?答案就是直接给Person绑定属性!

>>>> Person.sexuality = None>>> P1 = Person("Wave", "25")>>> print P1.sexualityNone>>> 
我们直接给Person绑定sexuality这个属性,重行实例化P1后。P1就有sexuality这个属性了!

那么function呢?怎么绑定?

>>> class Person():def __init__(self, name = None, age = None):    self.name = name    self.age = agedef 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>>> 

绑定我们了解了,可是怎么删除呢?

请看下面样例首先给的是属性的真删:

>>> P.name‘The_Third_Wave‘>>> P.sexTraceback (most recent call last):  File "<pyshell#32>", line 1, in <module>    P.sexAttributeError: Person instance has no attribute ‘sex‘>>> setattr(P, "sex", "male") # 増>>> P.sex‘male‘>>> delattr(P, "name") # 删>>> P.nameTraceback (most recent call last):  File "<pyshell#36>", line 1, in <module>    P.nameAttributeError: Person instance has no attribute ‘name‘>>> 

加入方法呢?

>>> class Person():def __init__(self, name = None, age = None):    self.name = name    self.age = agedef 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‘>>> 

通过以上样例能够得出一个结论:相对于动态语言,静态语言具有严谨性!

所以。玩动态语言的时候,小心动态的坑!

那么怎么避免这样的情况呢?请使用__slots__。可是我的是2.7.6版本号,測试是不行的。代码例如以下:

>>> class Person():__slots__ = ("location", "run")def __init__(self, name = None, age = None):    self.name = name    self.age = age    def eat(self):    print "eat food"    >>> P = Person()>>> P.sexTraceback (most recent call last):  File "<pyshell#3>", line 1, in <module>    P.sexAttributeError: Person instance has no attribute ‘sex‘>>> P.sex = "male">>> 

详细原因是什么呢,本来是准备请等待更新:ing...的

BUT。我多写了个object就出来了。。。

这可真是个神坑!soga!

>>> class Person(object):__slots__ = ("location", "run")def __init__(self, name = None, age = None):    self.name = name    self.age = age    def eat(self):    print "eat food"    >>> P = Person()Traceback (most recent call last):  File "<pyshell#12>", line 1, in <module>    P = Person()  File "<pyshell#11>", line 5, in __init__    self.name = nameAttributeError: ‘Person‘ object has no attribute ‘name‘ # 顺便还发现了个注意事项:要预先定义的属性也要写到tuple里面!

>>> class Person(object):__slots__ = ("name", "age", "eat", "location", "run")def __init__(self, name = None, age = None): self.name = name self.age = age def eat(self): print "eat food" >>> P = Person()>>> P.sex = "male"Traceback (most recent call last): File "<pyshell#16>", line 1, in <module> P.sex = "male"AttributeError: ‘Person‘ object has no attribute ‘sex‘>>> P.location = "china">>> P.location‘china‘>>> def run(self, speed):print "Keeping moving, the speed is %s km/h" %speed>>> setattr(P, "run", run)>>> P.run(u"请注意这儿參数和上面有个样例不一样哦", 720)Keeping moving, the speed is 720 km/h>>>

顺便还发现了个注意事项:要预先定义的属性也要写到tuple里面!

临时写到这,不定期更新ing...

关于slots的demo原文:https://docs.python.org/2/reference/datamodel.html?

highlight=__slots__#__slots__

本文由@The_Third_Wave原创。不定期更新。有错误请指正。

Sina微博关注:@The_Third_Wave?

假设这篇博文对您有帮助,为了好的网络环境,不建议转载,建议收藏!假设您一定要转载。请带上后缀和本文地址。

为什么说Python是一门动态语言--Python的魅力

评论关闭