• Python动态语言的特性


    一、动态语言相关概念

    1.1 动态语言

    • 在运行时代码可以根据某些条件改变自身结构
    • 可以在运行时引进新的函数、对象、甚至代码,可以删除已有的函数等其他结构上的变化
    • 常见的动态语言:Object-C、C#、JavaScript、PHP、Python、Erlang

    1.2 动态类型语言

    • 在运行期间检查数据类型的语言
    • 数据类型不是在编译阶段决定的,而是把类型绑定延后到了运行阶段
    • 常见的动态类型语言:Python、Ruby、Erlang、JavaScript、swift、PHP、Perl

    1.3 强类型语言

    • 一旦一个变量被指定了某个数据类型,如果不经过强制类型转换,那么它就永远是这个数据类型
    • 常见的强类型语言:Java、C#、Python、Object-C、Ruby

    Python是动态语言,动态类型语言,也是强类型语言。所以Python可以在运行时改变自身结构,动态添加/删除属性和方法。接下来将介绍Python如何动态添加属性和方法。

    二、动态添加属性

     2.1 添加对象属性

    class Obj(object):
        def __init__(self):
            self.name = '张亚飞'
    
    
    obj = Obj()
    obj.age = 23
    print(obj.age)
    obj2 = Obj()
    print(obj2.age)
    由以上代码可知,Obj类有两个属性:name和age。通过[对象名.属性名]给类对象obj动态添加了对象属性addr,而Obj的另一个类对象obj2却不能调用这个属性。
    注:通过对象名添加的对象属性,只有这个对象能使用

    2.2 添加类属性

    Obj.score = 100
    print(obj.score)
    print(obj2.score)
     由以上代码可知,通过[类名.属性名]给类Obj动态添加了类属性addr,Obj的类对象obj和obj2都能调用这个属性
        注:通过类名添加的类属性,这个类的所有对象都能使用
     

    三、动态添加方法

    类中有三种方法,实例方法,静态方法和类方法,三种方法的区别如下:
    实例方法:需要绑定要一个对象上,第一个参数默认使用self,会把对象作为第一个参数传递进来
    静态方法:使用装饰器@staticmethod进行定义,类和对象都可以调用,不需要默认参数
    类方法:使用装饰器@classmethod进行定义,类和对象都可以调用,第一个参数默认使用cls,会把类作为第一个参数传递进来

    from types import MethodType
    
    
    class Obj(object):
        # __slots__ = ('name', 'age')
    
        def __init__(self):
            self.name = '张亚飞'
    
    
    def set_score(self, score):
        self.score = score
    
    
    @staticmethod
    def static_func():
        print('static_func')
    
    
    @classmethod
    def class_func(cls):
        print('class_method')
    “““
    类中有三种方法,实例方法,静态方法和类方法,三种方法的区别如下:
    实例方法:需要绑定要一个对象上,第一个参数默认使用self,会把对象作为第一个参数传递进来
    静态方法:使用装饰器@staticmethod进行定义,类和对象都可以调用,不需要默认参数
    类方法:使用装饰器@classmethod进行定义,类和对象都可以调用,第一个参数默认使用cls,会把类作为第一个参数传递进来
    ”””
    # 动态添加实例方法
    obj = Obj()
    obj.set_score = MethodType(set_score, obj) obj.set_score(99) print(obj.score) # 99
    obj2.set_score(99) #
    AttributeError: 'Obj' object has no attribute 'set_score'
    """
    由以上代码可知,Obj类有一个方法:eat()方法。通过[types.MethodType(方法名, 对象名)]给类对象zhangsan动态添加了对象方法run(),同理,Obj的另一个类对象lisi不能调用这个方法
    注:通过对象名添加的对象方法,只有这个对象能使用
    """
    # 添加静态方法
    Obj.static_func = static_func
    Obj.static_func()
    obj.static_func()
    obj2.static_func()
    """ 由以上代码可知,通过[类名.静态方法名]给类Obj动态添加了静态方法static_func(),Obj类的Obj对象和obj2对象都能调用这个方法 注:通过类名添加的静态方法,这个类及这个类的所有对象都能使用 """ # 添加类方法 Obj.class_func = class_func Obj.class_func() obj.class_func()
    obj2.class_func()
    """ 由以上代码可知,通过[类名.类方法名]给类Obj动态添加了类方法class_func(),Obj类的obj对象和obj2对象都能调用这个方法 注:通过类名添加的类方法,这个类及这个类的所有对象都能使用 """

    四、__slots__的使用

      通过以上内容,我们知道了如何动态的添加属性和方法。但是,如果我们想要限制class的属性该怎么办?例如:只允许Obj实例添加name和age属性。为了达到这个目的,Python允许在定义class的时候,定义一个特殊变量__slots__来限制该class能添加的属性。

    class Obj(object):
        __slots__ = ('name', 'age')
    
    obj = Obj() obj.name
    = 'zhangyafei' obj.age = 23 obj.score = 99 # AttributeError: 'Obj' object has no attribute 'score' Obj.score = 100 print(obj.score) # 100 obj.score = 99 # AttributeError: 'Obj' object attribute 'score' is read-only

    通过以上代码可知,__slots__对Obj类的动态添加没有限制,而Obj类对象obj不能再动态添加对象属性和方法。

    对于__slot__有以下几个需要注意的地方:

    • __slots__只对类对象进行限制,不对类进行限制
    • __slots__不仅限制类对象的属性,还限制类对象的方法
    • __slots__仅对当前类起作用,对继承的子类不起作用
    • 在子类中定义__slots__,子类允许定义的属性就是自身的__slots__加上父类的__slots__
  • 相关阅读:
    搭建Flask+Vue及配置Vue 基础路由
    vue dev 环境下的跨域访问
    vue 调用常量的config.js文件
    PyCharm 通过Github和Git上管理代码
    MongoDB 配置服务
    2018年11月12日
    搭建 flask 应用
    Python 错误总结
    搭建 Django 平台
    go实现主线程等待子线程都运行完再退出
  • 原文地址:https://www.cnblogs.com/zhangyafei/p/10170854.html
Copyright © 2020-2023  润新知