• Python随笔12


    Python是动态语言,可以在运行时改变其结构,比如给类添加属性、方法,引入代码,已有的函数被删除或者其它结构上的改变。

    给实例绑定属性和方法:

      定义一个空类Person,用到代码桩(Pass,暂时没有逻辑代码,用Pass占位,代码执行到这里,继续向下执行),给它的实例绑定属性和方法。

    class Person(object):
        pass
    #类的实例
    s = Person()
    #给空类的实例绑定属性
    s.name = "Jerry"
    print(s.name)
    #定义一个方法
    def set_age(self,age):
        self.age = age
    
    from types import MethodType
    # Python3中,用types.MethodType(methodName,instance),可以把一个方法绑定到实例对象上,同样也可以把方法绑定到类中
    #返回值是methodName对应的方法anotherRef,这个anthodRef可以调用methodName对应的方法,把instance当作self
    s.set_age = MethodType(set_age,s)
    s.set_age(25)
    print(s.age)

      输出的结果为: 

    Jerry
    25

      可以看到,原本一个空类,现在我们给它的实例绑定了属性name和set_age()方法。那么在另外一个实例中,是否可以也有这些属性和方法呢?

    s2 = Person()
    print(hasattr(s2,"name"))

      我们用hasattr()可以查看实例s2是否有name属性,返回结果为False,说明s2没有name属性。再来看是否有set_age()方法。

    s2.set_age(30)
    print(s2.age) 

      结果报这样一个错,AttributeError: 'Person' object has no attribute 'set_age'。说明set_age()方法也不能用在s2这个实例上。

      事实上,给类的实例绑定的属性和方法是不能适用于其他实例的。

     给空类绑定属性和方法:

    class Person(object):
        pass
    
    def set_age(self,age):
        self.age = age
    #类名.属性=值 给类绑定属性
    Person.name = "www"
    Person.set_age =set_age
    p1 = Person()
    p1.set_age(18)
    print(p1.age)
    p2 = Person()
    p2.set_age(30)
    print(p2.age)
    print(p1.name)
    #查看类中是否有这个name属性
    print(hasattr(Person,"name"))

     结果为: 

    18
    30
    www
    True

      可以看到,成功的给类绑定了属性和方法,在类的实例中可以直接调用绑定的方法,也可以访问绑定的属性。同样也可以用TypeMethod()方法给类动态的绑定方法

    class Person(object):
        pass
    
    def set_age(self,age):
        self.age = age
    
    from types import MethodType
    #实例化对象和类都是对象,所以types.MethodType()方法同样也实用于方法
    # 但是通过这种方法给类绑定方法,set_age就是给类设置属性了,所以以最后一个为准
    Person.set_age = MethodType(set_age,Person)
    p1 = Person()
    p2 = Person()
    p1.set_age(22)
    p2.set_age(88)
    print(p1.age)           #输出为88
    print(p2.age)

      结果为:

    88
    88

      可以看到,成功的给类绑定了方法,但是set_age()方法也给类设置了属性,所以每一个类的实例都会更改age属性的值,以最后一个为准。

      __slots__,限制类的属性,意思就是如果在一个类中存在__slots__ = (arg1,arg2)那么就意味着这个类的实例只能有arg1和arg2两个属性,不能用实例动态的绑定属性。值对类的实例有效,对于子类的实例不受此限制。

    class Person(object):
        __slots__ = ("name","age")      #限制这个类的实例只能有name和age两个属性
    
    p = Person()
    p.name = "Tom"
    p.age = 8
    print(p.name,p.age)
    
    p.weight = 20
    print(p.weight) 

      结果为:

    Tom 8
    Traceback (most recent call last):
      File "D:/PythonDemo/动态语言-__slots__.py", line 11, in <module>
        p.weight = 20
    AttributeError: 'Person' object has no attribute 'weight'

      可以看到,类的实例不能再绑定其他属性了

      但是子类就不受此限制

    class A(Person):
        pass
    
    a1 = A()
    a2 = A()
    a1.name = "Tom"
    a1.age = 10
    a1.weight = 11
    a2.name = "Jerry"
    a2.age = 5
    a2.weight = 2
    print(a1.name,a1.age,a1.weight)
    print(a2.name,a2.age,a2.weight)

      结果为:

    Tom 10 11
    Jerry 5 2
  • 相关阅读:
    linux basename 和 dirname 获取当前路径
    灵活的装饰器
    ubuntu 20version install wechat
    git pull 总提示让输入merge 信息
    Linux脚本中$#、$0、$1、$@、$*、$$、$?
    ansible
    MMD讲解
    再生希尔伯特空间与核函数讲解
    流形学习
    聚类
  • 原文地址:https://www.cnblogs.com/bigbigtong/p/10259749.html
Copyright © 2020-2023  润新知