• python中self,cls


    cls主要用在类方法定义,而self则是实例方法。

    self, cls 不是关键字,完全可以使用自己写的任意变量代替实现一样的效果。

    普通的实例方法,第一个参数需要是self,它表示一个具体的实例本身。
    如果用了staticmethod,那么就可以无视这个self,而将这个方法当成一个普通的函数使用。
    而对于classmethod,它的第一个参数不是self,是cls,它表示这个类本身。
    >>> class A(object):


        def foo1(self):
            print "Hello",self


        @staticmethod
        def foo2():
            print "hello"


        @classmethod
        def foo3(cls):
            print "hello",cls

           
    >>> a = A()
    >>> a.foo1()          #最常见的调用方式,但与下面的方式相同
    Hello <__main__.A object at 0x9f6abec>
    >>> A.foo1(a)         #这里传入实例a,相当于普通方法的self
    Hello <__main__.A object at 0x9f6abec>
    >>> A.foo2()          #这里,由于静态方法没有参数,故可以不传东西
    hello
    >>> A.foo3()          #这里,由于是类方法,因此,它的第一个参数为类本身。
    hello <class '__main__.A'>
    >>> A                 #可以看到,直接输入A,与上面那种调用返回同样的信息。
    <class '__main__.A'>

    ---------------------------------------------------------------------------------

    类的定义可以动态修改

    class MyTest:
        
        myname = 'peter'

        def sayhello(self):
            print "say hello to %s" % self.myname

    if __name__ == "__main__":
        MyTest.myname = 'hone'
        MyTest.sayhello = lambda self, name: "I want say hello to %s" % name
        MyTest.saygoodbye = lambda self,name: "I do not want say goodbye to %s" % name
        print MyTest().sayhello(MyTest.myname)
        print MyTest().saygoodbye(MyTest.myname)

    这里修改了MyTest类中的变量和函数定义, 实例化的instance有了不同的行为特征。

    -------------------------------------------------------------------------------------

    1.Python是一门动态语言,任何实体都可以动态地添加或删除属性。
    2.一个类定义了一个作用域。
    3.类实例也引入了一个作用域,这与相应类定义的作用域不同。
    4.在类实例中查找属性的时候,首先在实例自己的作用域中查找,如果没有找到,则再在类定义的作用域中查找。
    5.在对类实例属性进行赋值的时候,实际上会在类实例定义的作用域中添加一个属性(如果还不存在的话),并不会影响到相应类中定义的同名属性。

    class A:
        cls_i = 0
        cls_j = {}
        
        def __init__(self):
            self.instance_i = 0
            self.instance_j = {}

    if __name__ == '__main__':
        a = A()
        print A.__dict__ #{'__init__': , '__module__': '__main__', 'cls_i': 0, 'cls_j': {}, '__doc__': None}
        print a.__dict__ # {'instance_j': {}, 'instance_i': 0}

    >>> a.cls_i
    0
    >>>
    a.instance_i
    0

    在查找cls_i的时候,实例a的作用域中是没有它的,却在A的作用域中找到了它;在查找instance_i的时候,直接可在a的作用域中找到它。


    如果我们企图通过实例a来修改cls_i的值,那会怎样呢:
    >>> a.cls_i = 1
    >>> a.__dict__
    {'instance_j': {}, 'cls_i': 1, 'instance_i': 0}
    >>> A.__dict__
    {'__init__': , '__module__': '__main__', 'cls_i': 0, 'cls_j': {},
    '__doc__': None}

    我们可以看到,a的作用域中多了一个cls_i属性,其值为1;同时,我们也注意到A作用域中的cls_i属性的值仍然为0;在这里,我们其实是增加了一个实例属性,并没有修改到类属性


    如果我们通过实例a操纵cls_j中的数据(注意不是cls_j本身),又会怎么样呢:
    >>> a.cls_j['a'] = 'a'
    >>> a.__dict__
    {'instance_j': {}, 'cls_i': 1, 'instance_i': 0}
    >>> A.__dict__
    {'__init__': , '__module__': '__main__', 'cls_i': 0, 'cls_j': {'a': 'a'}, '__doc__': None}

    我们可以看到a的作用域没有发生什么变化,但是A的作用域发生了一些变化,cls_j中的数据发生了变化。

    实例的作用域发生变化,并不会影响到该类的其它实例,但是类的作用域发生变化,则会影响到该类的所有实例,包括在这之前创建的实例.
  • 相关阅读:
    循环语句 for , forin , forEach
    Haxe
    Haxe数据类型
    jango中间件的使用
    python的遍历模式
    python文件读写
    python3.5以上自带的虚拟环境在各种环境下的使用方法
    冒泡排序
    工厂方法模式
    redis 配置
  • 原文地址:https://www.cnblogs.com/kex1n/p/5983200.html
Copyright © 2020-2023  润新知