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中的数据发生了变化。 实例的作用域发生变化,并不会影响到该类的其它实例,但是类的作用域发生变化,则会影响到该类的所有实例,包括在这之前创建的实例.

python中self,cls的更多相关文章

  1. python中self cls init的理解

    原创文章,未经允许禁止转载! python中self cls init的理解 python中self cls init的理解

  2. python中的cls到底指的是什么

    python中的cls到底指的是什么,与self有什么区别? 2018年07月31日 11:13:09 rs勿忘初心 阅读数:7769   作者:秦风链接:https://www.zhihu.com/ ...

  3. Python中的类、对象、继承

    类 Python中,类的命名使用帕斯卡命名方式,即首字母大写. Python中定义类的方式如下: class 类名([父类名[,父类名[,...]]]): pass 省略父类名表示该类直接继承自obj ...

  4. python2.7高级编程 笔记二(Python中的描述符)

    Python中包含了许多内建的语言特性,它们使得代码简洁且易于理解.这些特性包括列表/集合/字典推导式,属性(property).以及装饰器(decorator).对于大部分特性来说,这些" ...

  5. [转载]python中的sys模块(二)

    #!/usr/bin/python # Filename: using_sys.py import sys print 'The command line arguments are:' for i ...

  6. Python中的__new__和__init__

    Python中的__new__和__init__ 写了这么多的class,现在才知道还有个__new__方法, 那么它和__init__有什么区别呢? class TestCls(): "& ...

  7. Python中的__init__和__new__介绍

    介绍 首先我们要知道在面向对象编程中,实例化基本遵循创建实例对象.初始化实例对象.最后返回实例对象这么一个过程. Python 中的 __new__ 方法负责创建一个实例对象,__init__ 方法负 ...

  8. python中的metaclass

    首先看下面的代码: # coding: utf-8 class Test(object): pass print Test.__class__ # type print Test.__base__ # ...

  9. python中的__init__ 、__new__、__call__小结

    这篇文章主要介绍了python中的__init__ .__new__.__call__小结,需要的朋友可以参考下 1.__new__(cls, *args, **kwargs)  创建对象时调用,返回 ...

  10. python中的实例方法、静态方法、类方法、类变量和实例变量

    class MyTest: myname = 'peter' # add a instance attribute    def __init__(self, name):        self.n ...

随机推荐

  1. C/C++的一些备忘

    今天使用source insight阅读videoserver源码,有一些符号ctrl+左键点击显示找不到,先是rebuild工程和同步,没有效果,然后Options->Preferences- ...

  2. 【转】MYSQL入门学习之九:索引的简单操作

    转载地址:http://www.2cto.com/database/201212/176772.html 一.创建索引  www.2cto.com           MYSQL常用的索引类型主要有以 ...

  3. combobox中动态加入几个checkbox,实现下拉框多选

    combobox中动态加入几个checkbox,实现下拉框多选,将一个checkbox选中时其内容就会在combobox中显示出来,将另一个checkbox选中时其内容会跟在第一个checkbox的内 ...

  4. c# 客户端

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  5. linux命令总结2

    昨天继续对239进行挖掘,想把运营登录浮层的示例页面放在这台测试机上,供大家使用,结果在配置apache时出现了问题,无论怎样,页面都是403 Forbidden,最后终于被露颖同学经过2个小时的努力 ...

  6. JAVA基础知识之网络编程——-TCP/IP协议,socket通信,服务器客户端通信demo

    OSI模型分层 OSI模型是指国际标准化组织(ISO)提出的开放系统互连参考模型(Open System Interconnection Reference Model,OSI/RM),它将网络分为七 ...

  7. [小技巧] git: Your branch and 'origin/master' have diverged

    本文参考:http://stackoverflow.com/questions/19864934/git-your-branch-and-origin-master-have-diverged-how ...

  8. linux rc.sysinit文件详解

    /etc/rc.d/rc.sysinit 系统初始化脚本的任务 .激活udev和selinux .根据/etc/sysctl.conf文件设定内核参数 .设定系统时钟 .装载键盘映射 .启用交换分区 ...

  9. VC++实现在系统托盘来新消息闪烁,鼠标悬停显示窗口

    转载:http://www.codeguru.com/cpp/com-tech/activex/tutorials/article.php/c8115/How-to-Implement-a-Mouse ...

  10. Xcode插件管理以及Xcode7 升级

    一,Xcode插件管理工具 Alcatraz: mkdir -p ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins; cur ...