python-静态方法staticmethod、类方法classmethod、属性方法property
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) |
类的普通方法
class Animal(object):
def __init__(self,name):
self.name = name
def intro(self):
print('there is a %s'%(self.name))
cat = Animal('cat')
cat.intro()
- 静态类方法
class Animal(object):
def __init__(self,name):
self.name = name
@staticmethod
def intro(self):
print('there is a %s'%(self.name))
cat = Animal('cat')
cat.intro()
- 加上装饰器后运行会报错,原因是方法变为一个普通函数,脱离的与类的关系,不能引用构造函数中的变量了。

使用场景举例:python内置方法os中的方法,可以直接使用的工具包,跟类没关系。
class Animal(object):
def __init__(self,name):
self.name = name
@classmethod
def intro(self):
print('there is a %s'%(self.name))
cat = Animal('cat')
cat.intro()
- 报错信息

如果换成
class Animal(object):
name = 'cat'
def __init__(self,name):
self.name = name
@classmethod
def intro(self):
print('there is a %s'%(self.name))
cat = Animal('cat')
cat.intro()
- 可以正常运行。
结论:类方法只能调用类变量,不能调用实例变量
属性方法@property 把一个方法变为(伪装成)类属性。因为类属性的实质是一个类变量,用户可以调用变量就可以修改变量。某些特定场景要限制用户行为,就用到静态方法。
@property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。(摘自廖雪峰的博客)
class Animal(object):
def __init__(self,name):
self.name = name
@property
def intro(self,food):
print('there is a %s eating %s'%(self.name,food))
cat = Animal('cat')
cat.intro()
- 报错:

- 方法不能正常调用。如果要调用,如下:
cat.intro
- 是这样的话,方法就没办法单独传入参数。如果要传入参数,如下:
class Animal(object):
def __init__(self,name):
self.name = name
@property
def intro(self):
print('there is a %s eating %s'%(self.name,food))
@intro.setter
def intro(self,food):
pass
cat = Animal('cat')
cat.intro
- cat.intro还有其他操作getter deleter等等。
一:staticmethod
class Singleton(object):
instance = None def __init__(self):
raise SyntaxError('can not instance, please use get_instance') @staticmethod
def get_instance():
if Singleton.instance is None:
Singleton.instance = object.__new__(Singleton)
return Singleton.instance a = Singleton.get_instance()
b = Singleton.get_instance()
print('a id=', id(a))
print('b id=', id(b))
该方法的要点是在__init__抛出异常,禁止通过类来实例化,只能通过静态get_instance函数来获取实例;因为不能通过类来实例化,所以静态get_instance函数中可以通过父类object.__new__来实例化。
二:classmethod
class Singleton(object):
instance = None def __init__(self):
raise SyntaxError('can not instance, please use get_instance') @classmethod
def get_instance(cls):
if Singleton.instance is None:
Singleton.instance = object.__new__(Singleton)
return Singleton.instance a = Singleton.get_instance()
b = Singleton.get_instance()
print('a id=', id(a))
print('b id=', id(b))
该方法的要点是在__init__抛出异常,禁止通过类来实例化,只能通过静态get_instance函数来获取实例;因为不能通过类来实例化,所以静态get_instance函数中可以通过父类object.__new__来实例化。
三:类属性方法
class Singleton(object):
instance = None def __init__(self):
raise SyntaxError('can not instance, please use get_instance') def get_instance():
if Singleton.instance is None:
Singleton.instance = object.__new__(Singleton)
return Singleton.instance a = Singleton.get_instance()
b = Singleton.get_instance()
print(id(a))
print(id(b))
该方法的要点是在__init__抛出异常,禁止通过类来实例化,只能通过静态get_instance函数来获取实例;因为不能通过类来实例化,所以静态get_instance函数中可以通过父类object.__new__来实例化。
四:__new__
常见的方法, 代码如下:
class Singleton(object):
instance = None def __new__(cls, *args, **kw):
if not cls.instance:
# cls.instance = object.__new__(cls, *args)
cls.instance = super(Singleton, cls).__new__(cls, *args, **kw)
return cls.instance a = Singleton()
b = Singleton()
print(id(a))
print(id(b))
五:装饰器
代码如下:
def Singleton(cls):
instances = {} def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance @Singleton
class MyClass:
pass a = MyClass()
b = MyClass()
c = MyClass() print(id(a))
print(id(b))
print(id(c))
六:元类
class Singleton(type):
def __init__(cls, name, bases, dct):
super(Singleton, cls).__init__(name, bases, dct)
cls.instance = None def __call__(cls, *args):
if cls.instance is None:
cls.instance = super(Singleton, cls).__call__(*args)
return cls.instance class MyClass(object):
__metaclass__ = Singleton a = MyClass()
b = MyClass()
c = MyClass()
print(id(a))
print(id(b))
print(id(c))
print(a is b)
print(a is c)
或者:
class Singleton(type):
def __new__(cls, name, bases, attrs):
attrs["_instance"] = None
return super(Singleton, cls).__new__(cls, name, bases, attrs) def __call__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instance class Foo(object):
__metaclass__ = Singleton x = Foo()
y = Foo()
print(id(x))
print(id(y))
class Singleton(type):
def __new__(cls, name, bases, attrs):
attrs['instance'] = None
return super(Singleton, cls).__new__(cls, name, bases, attrs) def __call__(cls, *args, **kwargs):
if cls.instance is None:
cls.instance = super(Singleton, cls).__call__(*args, **kwargs)
return cls.instance class Foo(metaclass=Singleton):
pass x = Foo()
y = Foo()
print(id(x))
print(id(y))
七:名字覆盖
class Singleton(object):
def foo(self):
print('foo') def __call__(self):
return self Singleton = Singleton() Singleton.foo() a = Singleton()
b = Singleton()
print(id(a))
print(id(b))
python-静态方法staticmethod、类方法classmethod、属性方法property的更多相关文章
- Python 静态方法、类方法和属性方法
Python 静态方法.类方法和属性方法 静态方法(staticmethod) staticmethod不与类或者对象绑定,类和实例对象都可以调用,没有自动传值效果,Python内置函数staticm ...
- Python 静态方法,类方法,属性方法
方法的使用 静态方法 - 只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性. class Dog(object): def __init__(self,name): self.nam ...
- Python静态方法、类方法、属性方法
静态方法 使用静态方法以后,相当于把下面的函数和类的关系截断了,它的作用相当于是类下面的一个独立函数,不会自动传入参数self. class people:..... @staticmethod de ...
- Python的3个方法:静态方法(staticmethod),类方法(classmethod)和实例方法
Python的方法主要有3个,即静态方法(staticmethod),类方法(classmethod)和实例方法,如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...
- Python面向对象静态方法,类方法,属性方法
Python面向对象静态方法,类方法,属性方法 属性: 公有属性 (属于类,每个类一份) 普通属性 (属于对象,每个对象一份) 私有属性 (属于对象,跟普通属性相似,只是不能通过对象直接访问) 方法: ...
- python中静态方法、类方法、属性方法区别
在python中,静态方法.类方法.属性方法,刚接触对于它们之间的区别确实让人疑惑. 类方法(@classmethod) 是一个函数修饰符,表是该函数是一个类方法 类方法第一个参数是cls,而实例方法 ...
- Python的程序结构[1] -> 方法/Method[1] -> 静态方法、类方法和属性方法
静态方法.类方法和属性方法 在 Python 中有三种常用的方法装饰器,可以使普通的类实例方法变成带有特殊功能的方法,分别是静态方法.类方法和属性方法. 静态方法 / Static Method 在 ...
- 面向对象【day08】:静态方法、类方法、属性方法(九)
本节内容 概述 静态方法 类方法 属性方法 总结 一.概述 前面我们已经讲解了关于类的很多东西,今天讲讲类的另外的特性:静态方法(staticmethod).类方法(classmethod).属性方法 ...
- Python笔记_第四篇_高阶编程_实例化方法、静态方法、类方法和属性方法概念的解析。
1.先叙述静态方法: 我们知道Python调用类的方法的时候都要进行一个实例化的处理.在面向对象中,一把存在静态类,静态方法,动态类.动态方法等乱七八糟的这么一些叫法.其实这些东西看起来抽象,但是很好 ...
- python 面向对象静态方法、类方法、属性方法、类的特殊成员方法
静态方法:只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性. 在类中方法定义前添加@staticmethod,该方法就与类中的其他(属性,方法)没有关系,不能通过实例化类调用方法使用 ...
随机推荐
- Django学习笔记第九篇--实战练习五--关于数据的改、删操作、数据库字段属性的设置和类视图
一.首先上代码.关于类视图: class register(View): #template_name = "templates/register.html" def get(se ...
- 理解CSS3 isolation: isolate的表现和作用
转自:http://www.zhangxinxu.com/wordpress/?p=5155 只要元素可以创建层叠上下文,就可以阻断mix-blend-mode! 于是,不仅仅是isolation:i ...
- poj1179 Polygon【区间DP】
Polygon Time Limit: 1000MS Memory Limit: 10000K Total Submissions:6633 Accepted: 2834 Descriptio ...
- document.compatMode介绍
来自:http://www.cnblogs.com/fullhouse/archive/2012/01/17/2324706.html 问题描述:看到阮一峰的博客里面的代码使用到了document.c ...
- session------>防表单重复提交
方法一:用js控制表单提交--->但是容易在客户端被篡改代码,还是要加的 方法二:session 先给每一个表带上唯一的标志,再把标志存入session 当session中标志和表上标志都不为空 ...
- 20165330 2017-2018-2 《Java程序设计》第1周学习总结
教材学习内容总结 java的历史,地位,特点. java的平台介绍 java应用程序的开发及源文件的编写规则 java反编译特点 安装JDK Windows上 在安装JDK后设置系统环境变量,因为我的 ...
- Ckeditor事件绑定
最近有个需求是要在点击CKeditor的时候触发某个判断的事件.试了一些方法都不可行,自己写的onclick时间都会被编辑器屏蔽.可以对对象加载完成绑定事件代码如下. CKEDITOR.instanc ...
- 剑指Offer——机器人的运动范围
题目描述: 地上有一个m行和n列的方格.一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子. 例如,当k为18时,机器人 ...
- LeetCode题目_Reverse Integer
最近在LeetCode上做题,写点东西记录一下,虽然自己做的都是些很水的题目,但是重在练手. 题号7:Reverse Integer,题目描述: Reverse digits of an intege ...
- Flask之flask-script
简介 Flask-Scropt插件为在Flask里编写额外的脚本提供了支持.这包括运行一个开发服务器,一个定制的Python命令行,用于执行初始化数据库.定时任务和其他属于web应用之外的命令行任务的 ...