• 给Python的类和对象动态增加属性和方法


    通常我们会将编程语言分为静态和动态。静态语言的变量是在内存中的有类型的且不可变化的,除非强制转换它的类型;动态语言的变量是指向内存中的标签或者名称,其类型在代码运行过程中会根据实际的值而定。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__只对当前类生效,对其子类不生效
  • 相关阅读:
    41 快速的复制一张表
    4 cdh 5.12 centos 6.10三节点安装
    40 insert语句的锁
    oracle 11g 数据库恢复技术 ---02 控制文件
    05 使用bbed跳过归档恢复数据文件
    Springboot 配置文件与对象之间进行映射之@ConfigurationProperties
    @ConditionalOnProperty来控制Configuration是否生效
    Oracle 服务名/实例名,Service_name 和Sid的区别
    @Value中冒号的作用
    springboot读取配置不存在报错
  • 原文地址:https://www.cnblogs.com/phyger/p/13639291.html
Copyright © 2020-2023  润新知