Chinaunix首页 | 论坛 | 博客
  • 博客访问: 468392
  • 博文数量: 63
  • 博客积分: 1485
  • 博客等级: 上尉
  • 技术积分: 596
  • 用 户 组: 普通用户
  • 注册时间: 2010-02-21 14:49
文章分类

全部博文(63)

文章存档

2018年(8)

2017年(25)

2016年(10)

2012年(6)

2010年(14)

我的朋友

分类: Python/Ruby

2017-01-01 17:44:20

看《Python基础教程》,对于这个部分的描述不多,理解起来不透彻。
网上很多相关的讨论、理解,都很好!知乎上的这个讲解还是不错的,还有图,很棒!
这个年代的程序员(或者其他行业的人),想学一些技术知识真的太方便了,网上去找,一大把!知识共享,就看你学不学了!

下面这个link对于初学者来说非常好,值得仔细看看:

对于想深入理解的人,下面这个link更棒,里面含有例子,对比了@staticmethod和@classmethod的不同以及用法(例如:继承):


目前我能接受的理解,其实似懂非懂:
- Python里,类和实例都是对象。
 这个对于写过C++的人来说,不太理解。好多人提到,在"静态语言"里(也就是C++一类),类的概念基本上是在编译的时候有意义。Python根本也没有编译期。
 什么是动态语言?
 随便找两个链接,其实,能把一个语言的优势发挥出来即可;了解一个语言的优势,以及适合做什么很重要。
 http://haohetao.iteye.com/blog/589070
 http://www.cnblogs.com/spmxlBlog/archive/2010/06/28/1766832.html


类和实例都是对象,那么他们肯定都有属于自己的变量,写了一个小例子:

点击(此处)折叠或打开

  1. class AA(object):
  2.     g=0                            # 这是类的变量的定义
  3.     def __init__(self,val):
  4.         print "global g: ", g      # 这是使用全局的变量,不是类的变量,也不是实例的变量,直接使用var 的方式
  5.         if val > AA.g:             # 这是使用类的变量,需要用 class.var 的方式使用
  6.             self.g=val             # 这是使用实例的变量,在类里面,就用 self.var 的方式使用;在类外面就用 obj.var 的方式调用
  7.         else:
  8.             self.g=AA.g

  9. g=111                              # 全局变量的定义
  10. print "AA.g: ", AA.g
  11. aa1=AA(10)
  12. aa2=AA(20)
  13. print "aa1.val: ", aa1.g
  14. print "aa2.val: ", aa2.g

  15. print "---------------"
  16. AA.g=100
  17. print "AA.g: ", AA.g
  18. aa3=AA(10)
  19. aa4=AA(20)
  20. print "aa3.val: ", aa3.g
  21. print "aa4.val: ", aa4.g
结果是:

点击(此处)折叠或打开

  1. AA.g: 0
  2. global g: 111
  3. global g: 111
  4. aa1.val: 10
  5. aa2.val: 20
  6. ---------------
  7. AA.g: 100
  8. global g: 111
  9. global g: 111
  10. aa3.val: 100
  11. aa4.val: 100

@staticmethod

- 可以引用哪些变量?
 可以使用全局变量,或者本类的类变量;不能使用本类的对象的变量。
- 如何调用该方法?
 可以用类名来调用:class.method()
 也可以用类的实例来调用:obj.method()    # 没想明白为什么可以这么调用
 也可以用实例找到类,进而调用:obj.__class__.method()

点击(此处)折叠或打开

  1. class AA(object):
  2.     def __init__(self):
  3.         print "--- init ----"
  4.     @staticmethod
  5.     def printme(oo):
  6.         print "this is: ", oo, type(oo)

  7. aa = AA()

  8. aa.printme(1)
  9. aa.__class__.printme('2')
  10. AA.printme(3.3)

输出:

点击(此处)折叠或打开

  1. --- init ----
  2. this is: 1
  3. this is: 2
  4. this is: 3.3

@classmethod

点击(此处)折叠或打开

  1. class AA(object):
  2.     def __init__(self):
  3.         print "--- init ----"
  4.     @classmethod                          # 跟上一个例子的区别 1
  5.     def printme(cls,oo):                  # 跟上一个例子的区别 2
  6.         print "this is: ", oo, type(oo)

  7. aa = AA()

  8. aa.printme(1)                   # 把aa作为第一个参数传递了进去,但是"printme"的"cls"是怎么解析的呢?
  9. aa.__class__.printme('2')       # 把谁作为第一个阐述传递进去的?没想明白
  10. AA.printme(3.3)                 # 把AA作为第一个参数传递进去的

输出结果,跟@staticmethod的输出是一模一样的!

那为什么要用@staticmethod方法,而不是用类以外的全局方法呢?

个人理解(可能有问题,欢迎指出问题):
@staticmethod是定义在类里面的,那么这个类就是他的命名空间。
比如说,有两个类Class_A和Class_B,假定:因为某种需求,在使用的时候,他们都需要判断一些环境变量是否定义了。
用普通的方法(没有绑定类),那么就得用到 isinstanceof 这个一般都不太建议用到的函数,因为不利于代码的扩展:

点击(此处)折叠或打开

  1. def check_env(oo):
  2. if oo isinstanceof Class_A:
  3. ...
  4. else if oo isinstanceof Class_B:
  5. ...
  6. else
用@staticmethod,那么就可以在各自的类里面进行定义了。
对于这个简单的例子,用@classmethod也是可以的。






阅读(1832) | 评论(0) | 转发(0) |
0

上一篇:Python的property,没懂

下一篇:Python的迭代

给主人留下些什么吧!~~