通常我们会将编程语言分为静态和动态。静态语言的变量是在内存中的有类型的且不可变化的,除非强制转换它的类型;动态语言的变量是指向内存中的标签或者名称,其类型在代码运行过程中会根据实际的值而定。Python就是典型的动态语言。
动态添加属性
当类或者对象的属性在需要增加的时候,对于不方便修改源码的情况下,我们可以选择动态的对其添加属性。
动态给对象添加属性
对象属性只在当前对象生效,在其他对象中是无法调用的。
定义一个类:
class Student(object): def __init__(self,name,age): self.name=name self.age=age 复制代码
执行:(给实例添加数学成绩属性并且初始化)
>>> from payhlib import Student >>> s=Student('phyger',18) >>> s.name 'phyger' >>> s.age 18 >>> s.math_score=100 >>> s.math_score 100 >>> ss=Student('xiaopang',28) >>> ss.name 'xiaopang' >>> ss.age 28 >>> ss.math_score Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Student' object has no attribute 'math_score' >>> 复制代码
动态给类添加属性
类属性在其所有的对象中都生效。
执行:(默认所有对象的音乐成绩为60,当然你也可以对其进行修改)
>>> from payhlib import Student >>> Student.music_score=60 >>> s1=Student('phyger',19) >>> s1.name 'phyger' >>> s1.age 19 >>> s1.music_score 60 >>> s2=Student('xiaopang',29) >>> s2.music_score 60 >>> 复制代码
动态添加方法
当类或者对象的方法在需要增加的时候,对于不方便修改源码的情况下,我们可以选择动态的对其添加方法。
动态给对象添加方法
给对象添加的方法只绑定在当前对象上,不对其他对象生效,而且需要传入self参数。
执行:(通过types.MethodType方法给a对象绑定sayhi方法)
>>> from payhlib import Student >>> a=Student('phyger',17) >>> def sayhi(self): ... print('hi...') ... >>> a.sayhi() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Student' object has no attribute 'sayhi' >>> import types >>> a.sayhi=types.MethodType(sayhi,a) >>> a.sayhi() hi... >>> b=Student('xiaopang',27) >>> b.sayhi() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Student' object has no attribute 'sayhi' >>> 复制代码
动态给类添加方法(类方法和静态方法)
给类添加的方法对它的所有对象都生效,添加类方法需要传入self参数,添加静态方法则不需要。
执行:(给类添加静态方法)
>>> from payhlib import Student >>> stu = Student('phyger',16) >>> @staticmethod ... def staticHi(): ... print('staticHi...') ... >>> Student.hi=staticHi >>> stu.hi <function staticHi at 0x000001CB617F13A8> >>> stu.hi() staticHi... >>> 复制代码
执行:(给类添加类方法)
因为类方法只能使用类变量,所以我们增加一个类变量home
class Student(object): home='china' def __init__(self,name,age): self.name=name self.age=age >>> from payhlib import Student >>> stu = Student('phyger',17) >>> @classmethod ... def classHi(self): ... print(self.home) ... >>> Student.chi=classHi >>> stu.chi() china >>> 复制代码
限制给类或对象添加的属性
假如我们只希望类或者对象有name,age,score三个属性,我们可以借助__slots__来做,而且无法添加其他属性。
修改类:
class Student(object): home='china' __slots__=('name','age','score') #init中变量必须在__slots__中 def __init__(self,name,age): self.name=name self.age=age 复制代码
执行:
>>> from payhlib import Student >>> st = Student('phyger',16) >>> st.name 'phyger' >>> st.age 16 >>> st.score Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: score >>> st.score =100 >>> st.score 100 >>> st.phone='123' #无法添加phone属性 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Student' object has no attribute 'phone' >>> 复制代码
多总结几点:
- 类属性是read-only的
- 静态方法无法使用类变量
- 类方法只能使用类变量,不能使用初始化变量
- __slots__数据类型为元组
- __slots__只对当前类生效,对其子类不生效