一、实现方法

class Function(object):
# 在类定义中定义变量
cls_variable = "class varibale" def __init__(self):
# 在构造函数中创建变量
self.__instance_variable = "instance variable" def instance_method(self):
print(self.cls_variable)
print(self.__instance_variable)
print("this is a instance method") @staticmethod
def static_method():
print(Function.cls_variable)
# print(Function.__instance_variable) 此处会报错,无法访问实例变量
print("this is a static method") @classmethod
def class_method(cls):
print(cls.cls_variable)
# print(cls.__instance_variable) 此处会报错,无法访问实例变量
print("this is a class method") @classmethod
def set_class_variable(cls):
cls.cls_variable = 'new class variable' def set_instace_varibale(self):
self.__instance_variable = 'new instance varibale' # 类实例可以调用类方法和静态方法
function1 = Function()
function1.set_class_variable()
function1.class_method()
function1.instance_method()
function1.static_method() function2 = Function()
function2.set_instace_varibale()
function2.class_method()
function2.instance_method()
function2.static_method()

1、从代码定义中,可以看到只是在默认传入参数的不同。

Function.class_method()
Function.static_method()
# 可以调用实例函数,只不过需要传入实例变量
Function.instance_method(function1)

2、从代码访问中,通过实例访问这三种方法是一样的。但是同时类访问时,不一样,实例函数需要传入实例。

3、函数访问变量中,有很大不同。

@classmethod
def class_method(cls):
print(cls.cls_variable)
# print(cls.__instance_variable) 此处会报错,无法访问实例变量

在init函数定义的是实例变量,因为变量前缀添加了self。在类开始时定义的类变量,不需要添加前缀。

在变量访问中,发现类函数和静态函数是无法直接访问实例变量的,因为在后续调用中,不知道是那个实例的。但是实例函数是可以访问类变量的。

4、修改变量的范围

new class variable
this is a class method
new class variable
instance variable
this is a instance method
new class variable
this is a static method

上图是function1中输出的结果。

new class variable
this is a class method
new class variable
new instance varibale
this is a instance method
new class variable
this is a static method
new class variable

这是function2的结果,则class variable都变化了。

如果通过类方法修改变量,则所有实例中的类变量都会修改,这个类似静态变量了

如果通过实例修改变量,只是修改对应的实例变量。

二、三者选择原则

通过第一节的分析,我们得知三者的不同,在访问权限和方式上,类方法和静态方法有很多相同之处。与实例方法的区别就是看看这个方法是不是实例独有的方法,或者需要访问实例变量的。另一个不同就是在继承上了。

1、类方法和静态方法

# -*- coding: utf-8 -*-
"""
@Time : 2017/12/29 9:50
@Author:dongbl
@Description:
""" class Function(object):
X = 1
Y = 2 @staticmethod
def averag(*mixes):
return sum(mixes) / len(mixes) @staticmethod
def static_method():
# 通过function调用,如果类名修改,此处需要修改不太方便
return Function.averag(Function.X, Function.Y) @classmethod
def class_method(cls):
return cls.averag(cls.X, cls.Y) class Subclass(Function):
X =3
Y = 5 @staticmethod
def averag(*mixes):
return sum(mixes) / 3 func = Subclass()
print(func.static_method())
print(func.class_method())

1、调用方式不同,另一方面就是如果类名修改,函数也修改

2、继承。这是两者最大的不同

1.5
2.6666666666666665

上面是两者的输出。

子类的实例继承了父类的static_method静态方法,调用该方法,还是调用的父类的方法和类属性。

子类的实例继承了父类的class_method类方法,调用该方法,调用的是子类的方法和子类的类属性。

这就是最大的不同,静态方法在类没有初始化,已经加载了,后续继承和她就没有关系了。同时静态方法关键明确指明了调用了Function的方法了,所以就无法修改了。这是本质。

三、类方法和实例方法

类中最常用的方法是实例方法, 即通过通过实例作为第一个参数的方法。

如果现在我们想写一些仅仅与类交互而不是和实例交互的方法会怎么样呢?在Python2.2以后可以使用@classmethod装饰器来创建类方法.

比如我们创建一个类:

class DateTest():
def __init__(self,year,month,day):
self.year = year
self.day = day
self.month = month def print_date(self):
print("{}:{}:{}".format(self.year,self.month,self.day))

如果用户输入的是“2017-12-02”这样的字符,我们在调用类之前就需要调整一下。

这个设计角度可以理解每个实例都可以调用这个转化函数。

# -*- coding: utf-8 -*-
"""
@Time : 2017/12/29 9:50
@Author:dongbl
@Description:
"""
class DateTest():
def __init__(self,year,month,day):
self.year = year
self.day = day
self.month = month def print_date(self):
print("{}:{}:{}".format(self.year,self.month,self.day)) @classmethod
def get_date(cls,string_date):
year,month,day = map(int,string_date.split('-'))
return cls(year,month,day) t = DateTest(2017,9,10)
r = DateTest.get_date("2017-12-09")
r.print_date()
t.print_date()

classmethod主要用途是作为构造函数。
Python只有一个构造函数__new__,如果想要多种构造函数就很不方便。只能在new里面写一堆if isinstance 。
有classmethod之后就可以用classmethod来写不同的构造函数,比如:
dict.fromkeys
fractions.Fraction.from_decimal
inspect.Signature.from_function
python里面大部分classmethod最后都是 return cls(XXX), return XXX.__new__ ()之类的

staticmethod主要用途是限定namespace,也就是说这个函数虽然是个普通的function,但是它只有这个class会用到,不适合作为module level的function。这时候就把它作为staticmethod。
如果不考虑namespace的问题的话直接在module里面def function就行了。

四、参考文献

1、python类的静态方法和类方法区别

2、知乎经典解答

python 类函数,实例函数,静态函数的更多相关文章

  1. 【引用】python 静态函数 类函数 实例函数

    1.关于定义类的一些奇特之处  今天在Python中定义一个类,很奇怪,不需要事先声明它的成员变量吗?暂时不知,先记录下来: class Account(object):    "一个简单的 ...

  2. python内置函数详细描述与实例演示

    python有许多内置函数,列出表格如下 内置函数 abs() delattr() hash() memoryview() set() all() dict() help() min() setatt ...

  3. python简单的函数定义和用法实例

    python简单的函数定义和用法实例 这篇文章主要介绍了python简单的函数定义和用法,实例分析了Python自定义函数及其使用方法,具有一定参考借鉴价值,需要的朋友可以参考下 具体分析如下: 这里 ...

  4. Python使用property函数定义的属性名与其他实例变量重名会怎么样?

    首先如果定义的属性名与该属性对应的操作方法操作的实例对象同名就会触发无穷的递归调用,相关部分请参考<Python案例详解:使用property函数定义与实例变量同名的属性会怎样?> 但如果 ...

  5. python中的函数

    Python 函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也 ...

  6. python 内置函数和函数装饰器

    python内置函数 1.数学相关 abs(x) 取x绝对值 divmode(x,y) 取x除以y的商和余数,常用做分页,返回商和余数组成一个元组 pow(x,y[,z]) 取x的y次方 ,等同于x ...

  7. python之super()函数

    python之super()函数 python的构造器奇特, 使用魔方. 构造器内对基类对象的初始化同样也很奇特, 奇特到没有半点优雅! 在构造器中使用super(class, instance)返回 ...

  8. Python日期时间函数处理

    所有日期.时间的 api 都在datetime模块内. 1 日期的格式化输出 datetime => string import datetime now = datetime.datetime ...

  9. 由Python的super()函数想到的

    python-super *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !im ...

随机推荐

  1. 解决C#调用执行js报检索 COM 类工厂中 CLSID 为 {0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC} 组件失败

    最近做了一个模拟请求的网站简化原网站的繁琐数据,提出有用的数据简单展示并完成post.由于原网站数据有js加密,所以我抓出原网站的js解密方法,由C#调用js得到解密后的数据. 整个抓包的框架是用的苏 ...

  2. Servlet案例4:用户注册

    数据库准备: CREATE DATABASE web; USE web; CREATE TABLE `user` ( `uid` ) NOT NULL, `username` ) DEFAULT NU ...

  3. Nginx---(main block)

    正常运行必备配置 1,user USERNAME [GROUPAME] ; 指定用于运行worker进程的用户和组:   user nginx nginx; 2, pid /PATH/TO/PID_F ...

  4. C# GroupBy分组的问题和解决

    起因 今天在公司做一个需求的时候,写的是面条代码,一个方法直接从头写到尾,其中用到了GroupBy,且GroupBy的KeySelector是多个属性而不是单个属性. 但是公司最近推行Clean Co ...

  5. Linux - 查看命令所属的软件包

    这里以查看netstat命令所属的软件包为例. CentOS:利用yum provides命令 netstat命令所属的软件包为net-tools [root@CentOS7 ~]# yum prov ...

  6. Win10手记-IIS部署网站问题解决

    最近在自己的Win10电脑上尝试部署ASP.NET网站时出现了问题,经过多方查找定位到IIS为问题来源. 开始之前 先描述下技术环境: 1.Windows 10 PC 2.Windows 自带的IIS ...

  7. javaweb目录结构简介

    以上图说明: bbs目录代表一个web应用 bbs目录下的html,jsp文件可以直接被浏览器访问 WEB-INF目录下的资源是不能直接被浏览器访问的 web.xml文件是web程序的主要配置文件 所 ...

  8. Mac下命令行批量重命名

    日常中碰到需要批量修改文件名怎么办?嗯,来终端先 案例:将Users/case目录下所有html文件修改为php文件 步骤: 1.进入目标文件夹 $ cd Users/case 2.执行以下命令 $ ...

  9. python TypeError: 'int' object is not callable 问题解决

    TypeError: 'int' object is not callable 这个错误的原因很简单 看下面的程序: def loss(a,b): return a-b loss = 0 loss = ...

  10. PyCharm的基本快捷键和配置简介

    快捷键 1.编辑(Editing)Ctrl + Space 基本的代码完成(类.方法.属性)Ctrl + Alt + Space 快速导入任意类Ctrl + Shift + Enter 语句完成Ctr ...