Python的方法主要有3个,即静态方法(staticmethod),类方法(classmethod)和实例方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def foo(x):
    print "executing foo(%s)"%(x)
  
class A(object):
    def foo(self,x):
        print "executing foo(%s,%s)"%(self,x)
  
    @classmethod
    def class_foo(cls,x):
        print "executing class_foo(%s,%s)"%(cls,x)
  
    @staticmethod
    def static_foo(x):
        print "executing static_foo(%s)"%x
  
a=A()

这个self和cls是对类或者实例的绑定,对于一般的函数来说我们可以这么调用foo(x),这个函数就是最常用的,它的工作跟任何东西(类,实例)无关.对于实例方法,我们知道在类里每次定义方法的时候都需要绑定这个实例,就是foo(self, x),为什么要这么做呢?因为实例方法的调用离不开实例,我们需要把实例自己传给函数,调用的时候是这样的a.foo(x)(其实是foo(a, x)).类方法一样,只不过它传递的是类而不是实例,A.class_foo(x).注意这里的self和cls可以替换别的参数,但是python的约定是这俩,还是不要改的好.

对于静态方法其实和普通的方法一样,不需要对谁进行绑定,唯一的区别是调用的时候需要使用a.static_foo(x)或者A.static_foo(x)来调用.

\ 实例方法 类方法 静态方法
a = A() a.foo(x) a.class_foo(x) a.static_foo(x)
A 不可用 A.class_foo(x) A.static_foo(x)

类的普通方法

  1. class Animal(object):
  2. def __init__(self,name):
  3. self.name = name
  4. def intro(self):
  5. print('there is a %s'%(self.name))
  6. cat = Animal('cat')
  7. cat.intro()
  • 静态类方法
  1. class Animal(object):
  2. def __init__(self,name):
  3. self.name = name
  4. @staticmethod
  5. def intro(self):
  6. print('there is a %s'%(self.name))
  7. cat = Animal('cat')
  8. cat.intro()
  • 加上装饰器后运行会报错,原因是方法变为一个普通函数,脱离的与类的关系,不能引用构造函数中的变量了。

使用场景举例:python内置方法os中的方法,可以直接使用的工具包,跟类没关系。


  1. class Animal(object):
  2. def __init__(self,name):
  3. self.name = name
  4. @classmethod
  5. def intro(self):
  6. print('there is a %s'%(self.name))
  7. cat = Animal('cat')
  8. cat.intro()
  • 报错信息

如果换成

  1. class Animal(object):
  2. name = 'cat'
  3. def __init__(self,name):
  4. self.name = name
  5. @classmethod
  6. def intro(self):
  7. print('there is a %s'%(self.name))
  8. cat = Animal('cat')
  9. cat.intro()
  • 可以正常运行。

结论:类方法只能调用类变量,不能调用实例变量


属性方法@property 把一个方法变为(伪装成)类属性。因为类属性的实质是一个类变量,用户可以调用变量就可以修改变量。某些特定场景要限制用户行为,就用到静态方法。 
@property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。(摘自廖雪峰的博客)

  1. class Animal(object):
  2. def __init__(self,name):
  3. self.name = name
  4. @property
  5. def intro(self,food):
  6. print('there is a %s eating %s'%(self.name,food))
  7. cat = Animal('cat')
  8. cat.intro()
  • 报错:
  • 方法不能正常调用。如果要调用,如下:
  1. cat.intro
  • 是这样的话,方法就没办法单独传入参数。如果要传入参数,如下:
  1. class Animal(object):
  2. def __init__(self,name):
  3. self.name = name
  4. @property
  5. def intro(self):
  6. print('there is a %s eating %s'%(self.name,food))
  7. @intro.setter
  8. def intro(self,food):
  9. pass
  10. cat = Animal('cat')
  11. cat.intro
  • cat.intro还有其他操作getter deleter等等。

一:staticmethod

代码如下:
  1. class Singleton(object):
  2. instance = None
  3.  
  4. def __init__(self):
  5. raise SyntaxError('can not instance, please use get_instance')
  6.  
  7. @staticmethod
  8. def get_instance():
  9. if Singleton.instance is None:
  10. Singleton.instance = object.__new__(Singleton)
  11. return Singleton.instance
  12.  
  13. a = Singleton.get_instance()
  14. b = Singleton.get_instance()
  15. print('a id=', id(a))
  16. print('b id=', id(b))

该方法的要点是在__init__抛出异常,禁止通过类来实例化,只能通过静态get_instance函数来获取实例;因为不能通过类来实例化,所以静态get_instance函数中可以通过父类object.__new__来实例化。

 

二:classmethod

和方法一类似,代码:
 
  1. class Singleton(object):
  2. instance = None
  3.  
  4. def __init__(self):
  5. raise SyntaxError('can not instance, please use get_instance')
  6.  
  7. @classmethod
  8. def get_instance(cls):
  9. if Singleton.instance is None:
  10. Singleton.instance = object.__new__(Singleton)
  11. return Singleton.instance
  12.  
  13. a = Singleton.get_instance()
  14. b = Singleton.get_instance()
  15. print('a id=', id(a))
  16. print('b id=', id(b))

该方法的要点是在__init__抛出异常,禁止通过类来实例化,只能通过静态get_instance函数来获取实例;因为不能通过类来实例化,所以静态get_instance函数中可以通过父类object.__new__来实例化。

 

三:类属性方法

和方法一类似, 代码:
  1. class Singleton(object):
  2. instance = None
  3.  
  4. def __init__(self):
  5. raise SyntaxError('can not instance, please use get_instance')
  6.  
  7. def get_instance():
  8. if Singleton.instance is None:
  9. Singleton.instance = object.__new__(Singleton)
  10. return Singleton.instance
  11.  
  12. a = Singleton.get_instance()
  13. b = Singleton.get_instance()
  14. print(id(a))
  15. print(id(b))

该方法的要点是在__init__抛出异常,禁止通过类来实例化,只能通过静态get_instance函数来获取实例;因为不能通过类来实例化,所以静态get_instance函数中可以通过父类object.__new__来实例化。

 

四:__new__

常见的方法, 代码如下:

  1. class Singleton(object):
  2. instance = None
  3.  
  4. def __new__(cls, *args, **kw):
  5. if not cls.instance:
  6. # cls.instance = object.__new__(cls, *args)
  7. cls.instance = super(Singleton, cls).__new__(cls, *args, **kw)
  8. return cls.instance
  9.  
  10. a = Singleton()
  11. b = Singleton()
  12. print(id(a))
  13. print(id(b))

五:装饰器

代码如下:

  1. def Singleton(cls):
  2. instances = {}
  3.  
  4. def getinstance():
  5. if cls not in instances:
  6. instances[cls] = cls()
  7. return instances[cls]
  8. return getinstance
  9.  
  10. @Singleton
  11. class MyClass:
  12. pass
  13.  
  14. a = MyClass()
  15. b = MyClass()
  16. c = MyClass()
  17.  
  18. print(id(a))
  19. print(id(b))
  20. print(id(c))

六:元类

python2版:
  1. class Singleton(type):
  2. def __init__(cls, name, bases, dct):
  3. super(Singleton, cls).__init__(name, bases, dct)
  4. cls.instance = None
  5.  
  6. def __call__(cls, *args):
  7. if cls.instance is None:
  8. cls.instance = super(Singleton, cls).__call__(*args)
  9. return cls.instance
  10.  
  11. class MyClass(object):
  12. __metaclass__ = Singleton
  13.  
  14. a = MyClass()
  15. b = MyClass()
  16. c = MyClass()
  17. print(id(a))
  18. print(id(b))
  19. print(id(c))
  20. print(a is b)
  21. print(a is c)

或者:

  1. class Singleton(type):
  2. def __new__(cls, name, bases, attrs):
  3. attrs["_instance"] = None
  4. return super(Singleton, cls).__new__(cls, name, bases, attrs)
  5.  
  6. def __call__(cls, *args, **kwargs):
  7. if cls._instance is None:
  8. cls._instance = super(Singleton, cls).__call__(*args, **kwargs)
  9. return cls._instance
  10.  
  11. class Foo(object):
  12. __metaclass__ = Singleton
  13.  
  14. x = Foo()
  15. y = Foo()
  16. print(id(x))
  17. print(id(y))
 
python3版:
  1. class Singleton(type):
  2. def __new__(cls, name, bases, attrs):
  3. attrs['instance'] = None
  4. return super(Singleton, cls).__new__(cls, name, bases, attrs)
  5.  
  6. def __call__(cls, *args, **kwargs):
  7. if cls.instance is None:
  8. cls.instance = super(Singleton, cls).__call__(*args, **kwargs)
  9. return cls.instance
  10.  
  11. class Foo(metaclass=Singleton):
  12. pass
  13.  
  14. x = Foo()
  15. y = Foo()
  16. print(id(x))
  17. print(id(y))
 

七:名字覆盖

代码如下:
  1. class Singleton(object):
  2. def foo(self):
  3. print('foo')
  4.  
  5. def __call__(self):
  6. return self
  7.  
  8. Singleton = Singleton()
  9.  
  10. Singleton.foo()
  11.  
  12. a = Singleton()
  13. b = Singleton()
  14. print(id(a))
  15. print(id(b))

python-静态方法staticmethod、类方法classmethod、属性方法property的更多相关文章

  1. Python 静态方法、类方法和属性方法

    Python 静态方法.类方法和属性方法 静态方法(staticmethod) staticmethod不与类或者对象绑定,类和实例对象都可以调用,没有自动传值效果,Python内置函数staticm ...

  2. Python 静态方法,类方法,属性方法

    方法的使用 静态方法 - 只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性. class Dog(object): def __init__(self,name): self.nam ...

  3. Python静态方法、类方法、属性方法

    静态方法 使用静态方法以后,相当于把下面的函数和类的关系截断了,它的作用相当于是类下面的一个独立函数,不会自动传入参数self. class people:..... @staticmethod de ...

  4. Python的3个方法:静态方法(staticmethod),类方法(classmethod)和实例方法

    Python的方法主要有3个,即静态方法(staticmethod),类方法(classmethod)和实例方法,如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...

  5. Python面向对象静态方法,类方法,属性方法

    Python面向对象静态方法,类方法,属性方法 属性: 公有属性 (属于类,每个类一份) 普通属性 (属于对象,每个对象一份) 私有属性 (属于对象,跟普通属性相似,只是不能通过对象直接访问) 方法: ...

  6. python中静态方法、类方法、属性方法区别

    在python中,静态方法.类方法.属性方法,刚接触对于它们之间的区别确实让人疑惑. 类方法(@classmethod) 是一个函数修饰符,表是该函数是一个类方法 类方法第一个参数是cls,而实例方法 ...

  7. Python的程序结构[1] -> 方法/Method[1] -> 静态方法、类方法和属性方法

    静态方法.类方法和属性方法 在 Python 中有三种常用的方法装饰器,可以使普通的类实例方法变成带有特殊功能的方法,分别是静态方法.类方法和属性方法. 静态方法 / Static Method 在 ...

  8. 面向对象【day08】:静态方法、类方法、属性方法(九)

    本节内容 概述 静态方法 类方法 属性方法 总结 一.概述 前面我们已经讲解了关于类的很多东西,今天讲讲类的另外的特性:静态方法(staticmethod).类方法(classmethod).属性方法 ...

  9. Python笔记_第四篇_高阶编程_实例化方法、静态方法、类方法和属性方法概念的解析。

    1.先叙述静态方法: 我们知道Python调用类的方法的时候都要进行一个实例化的处理.在面向对象中,一把存在静态类,静态方法,动态类.动态方法等乱七八糟的这么一些叫法.其实这些东西看起来抽象,但是很好 ...

  10. python 面向对象静态方法、类方法、属性方法、类的特殊成员方法

    静态方法:只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性. 在类中方法定义前添加@staticmethod,该方法就与类中的其他(属性,方法)没有关系,不能通过实例化类调用方法使用 ...

随机推荐

  1. Linux命令之乐--find

    find是命令行工具箱中最棒的命令之一. 列出当前目录及其子目录中的文件和文件夹. [root@LAMP WebRoot]# find . -print../index.jsp./upload.jsp ...

  2. java如何发起一次http的post请求?

    @RequestMapping(value = "loginInSSO", method = RequestMethod.GET) public String loginInSSO ...

  3. zookeeper报错Will not attempt to authenticate using SASL (unknown error)

    Will not attempt to authenticate using SASL (unknown error) 转自:http://blog.csdn.net/mo_xingwang/arti ...

  4. 微信openid的单脚本获取 将 header 至自身,但是reques参数不同,响应也不同-----“单脚本APP”

    w 0-目的是封装成一个类.方法,方便在不同入口下,比如不是在微信公众号内而是在他人分享的url,获取opeid,且便于路由控制,将路由控制交给且仅交给codeigniter; 1-任何一个网站都可以 ...

  5. 牛B三人组-快速排序-堆排序-归并排序

    快速排序 随便取个数,作为标志值,这里就默认为索引位置为0的值 记录左索引和右索引,从右往左找比标志值小的,小值和左索引值交换,右索引变化,然后从左往右找比标志值大的,大值和右索引值交换,左索引变化 ...

  6. 借助 Django 的 smart_str 和 smart_unicode 进行编码转换(转)

    原文:http://www.dirk.sh/diary/using-django-smart_str-smart_unicode/ Django 为字符编码的转换提供了非常简洁的方法: 1.djang ...

  7. HTTP API 设计指南(转)

    add by zhj (2014-12-16): 今天才知道,原画HeroKu是国外一个很有名的PaaS提供商,公司很可能会将app迁移到他们那里 英文原文: HTTP API Design Guid ...

  8. Using virtual lists

    Download demo project - 15.7 Kb Contents Introduction Virtual list Creating a virtual list Add items ...

  9. MySQL存储引擎与事务

    1.作用 和磁盘的数据打交道 2.简介 MySQL  基于存储引擎管理 表空间数据数据文件 3.种类 Innodb存储引擎ibd:存储表的数据行和索引frm:表基本结构信息Myisam存储引擎frmm ...

  10. Mybatis框架学习总结-解决字段名与实体类属性名不相同的冲突

    在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定是完全相同的. 1.准备演示需要使用的表和数据 CREATE TABLE orders( order_id INT PRIMARY KEY ...