动态语言__slots__

Posted juno3550

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态语言__slots__相关的知识,希望对你有一定的参考价值。

1. 动态语言

1.1 运行过程中给对象添加属性

1.2 运行过程中给类添加属性

1.3 运行过程中给类添加方法

1.4 运行过程中删除属性、方法

2. __slots__

 

 

1. 动态语言

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

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

 

1.1 运行的过程中给对象添加属性

1 >>> class Person:
2 ...     def __init__(self, name, age):
3 ...             self.name = name
4 ...             self.age = age
5 ...
6 >>> p = Person("xiaoming", 25)
7 >>> p.gender = "male"  # 在类的定义中并没有 gender 属性,却可以添加
8 >>> p.gender
9 male

这就是动态语言的魅力和坑。这里实际上就是动态地给实例添加属性。

 

 1.2 运行的过程中给类添加属性

1 >>> p1 = Person("xiaojun", 24)  # 给类对象添加类属性
2 >>> p1.gender
3 >>> Person.gender = 0  
4 >>> p1 = Person("xiaojun", 24)
5 >>> p1.gender  # 如果实例对象没有gender属性,那么就会访问类属性
6 0

 

 1.3 运行的过程中给类添加方法

  • 给类对象添加方法:类名.方法名 = xxxx
  • 给对象添加方法:对象.方法名 = xxxx
 1 import types
 2 
 3 
 4 # 定义一个初始的类
 5 class Person:
 6     
 7     speed = 0
 8     
 9     def __init__(self, name, age):
10         self.name = name
11         self.age = age
12         
13     def eat(self):
14         print("eat food")
15         
16 
17 # 定义一个实例方法
18 def run(self, speed):
19     print("{} 在移动,速度为 {} km/h".format(self.name, speed))
20     
21 
22 # 定义一个类方法
23 @classmethod
24 def testClassMethod(cls):
25     cls.speed = 100
26     
27     
28 # 定义一个静态方法
29 @staticmethod
30 def testStaticMethod():
31     print("--static method--")
32     
33 
34 # 创建一个实例对象
35 p = Person("xiaoming", 25)
36 p.eat()  # 调用在类中定义的方法
37 
38 # 给这个对象添加实例方法
39 p.run = types.MethodType(run, p)  
40 # 调用添加的实例方法
41 p.run(180)  # "xiaoming 在移动,速度为 180 km/h"
42 
43 # 给类对象添加类方法
44 Person.testClassMethod = testClassMethod
45 print(Person.speed)  # 0
46 # 调用添加的类方法
47 Person.testClassMethod()
48 print(Person.speed)  # 100
49 
50 # 给类对象添加静态方法
51 Person.testStaticMethod = testStaticMethod
52 # 调用静态方法
53 Person.testStaticMethod()  # "--static method--"

 

1.4 运行的过程中删除属性、方法

删除的方法:

  • del 对象.属性名
  • delattr(对象, "属性名")

通过以上例子可以得出一个结论:相对于动态语言,静态语言具有严谨性!所以,玩动态语言的时候,小心动态的坑!

那么怎么避免这种情况呢? 请使用 __slots__ 。

 

2. __slots__

如果我们想要限制实例的属性怎么办?比如,只允许对 Person 实例添加 name 和 age 属性。

为了达到限制的目的,Python 允许在定义 class 的时候,定义一个特殊的 __slots__ 变量,来限制该 class 实例能添加的属性:

 1 >>> class Person:
 2 ...     __slots__ = ("age", "name")
 3 ...
 4 >>> p = Person()
 5 >>> p.age = 12
 6 >>> p.name = "xiaoming"
 7 >>> p.hobby = "football"
 8 Traceback (most recent call last):
 9   File "<stdin>", line 1, in <module>
10 AttributeError: Person object has no attribute hobby

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

1 >>> class Student(Person):
2 ...     pass
3 ...
4 >>> s = Student()
5 >>> s.hobby = "football"
6 >>>

 

以上是关于动态语言__slots__的主要内容,如果未能解决你的问题,请参考以下文章

1.3. __slots__

python的动态性和_slot_

Python3 __slots__

Python __slots__限制动态添加变量

动态绑定方法与 __slots__

python 动态给实例添加属性和方法并使用__slots__