python 类函数,实例函数,静态函数
一、实现方法
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就行了。
四、参考文献
2、知乎经典解答
python 类函数,实例函数,静态函数的更多相关文章
- 【引用】python 静态函数 类函数 实例函数
1.关于定义类的一些奇特之处 今天在Python中定义一个类,很奇怪,不需要事先声明它的成员变量吗?暂时不知,先记录下来: class Account(object): "一个简单的 ...
- python内置函数详细描述与实例演示
python有许多内置函数,列出表格如下 内置函数 abs() delattr() hash() memoryview() set() all() dict() help() min() setatt ...
- python简单的函数定义和用法实例
python简单的函数定义和用法实例 这篇文章主要介绍了python简单的函数定义和用法,实例分析了Python自定义函数及其使用方法,具有一定参考借鉴价值,需要的朋友可以参考下 具体分析如下: 这里 ...
- Python使用property函数定义的属性名与其他实例变量重名会怎么样?
首先如果定义的属性名与该属性对应的操作方法操作的实例对象同名就会触发无穷的递归调用,相关部分请参考<Python案例详解:使用property函数定义与实例变量同名的属性会怎样?> 但如果 ...
- python中的函数
Python 函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也 ...
- python 内置函数和函数装饰器
python内置函数 1.数学相关 abs(x) 取x绝对值 divmode(x,y) 取x除以y的商和余数,常用做分页,返回商和余数组成一个元组 pow(x,y[,z]) 取x的y次方 ,等同于x ...
- python之super()函数
python之super()函数 python的构造器奇特, 使用魔方. 构造器内对基类对象的初始化同样也很奇特, 奇特到没有半点优雅! 在构造器中使用super(class, instance)返回 ...
- Python日期时间函数处理
所有日期.时间的 api 都在datetime模块内. 1 日期的格式化输出 datetime => string import datetime now = datetime.datetime ...
- 由Python的super()函数想到的
python-super *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !im ...
随机推荐
- APK防护——Anti_Virtual App的思路和实现
作者:HAI_i 原文来自:https://bbs.ichunqiu.com/thread-42982-1-1.html 0×00 前言 Virtual App是一个很强大的存在,破坏了Android ...
- LeetCode--No.006 ZigZag Conversion
6. ZigZag Conversion Total Accepted: 98584 Total Submissions: 398018 Difficulty: Easy The string &qu ...
- 【2019北京集训测试赛(十三)】数据(sj) 冷静分析
题目大意:给你一个代表区间$[1,n]$的线段树,问你随机访问区间$[1,n]$中的一个子区间,覆盖到的线段树节点个数的期望(需要乘上$\frac{n(n-1)}{2}$后输出). 数据范围:$n≤1 ...
- Python基础教程(第3版) 笔记(二)
1.8模块Python提供了完成(某人的年 龄为32.9,并想将这个值向下圆整为32,因为他还没有满33岁)这种任务的函 数floor.导入模块,可以使用特殊命令import.函数floor包含在模块 ...
- shell中的算数
加法:let result=var1+var2result=$[$var1+var2]result=$(($var1+var2))result=`expr $var1 + $var2*` 加号前后有空 ...
- app自动化测试中的相关api
这个说的api即python自动化测试中经常会使用到的一些api,具体如下: 1.find_element_by_id/find_elements_by_id 定位元素api,使用方法如下: driv ...
- Zabbix系列之三——部署JMX监控tomcat
zabbix提供了一个java gateway的应用去监控jmx(Java Management Extensions,即Java管理扩展)是一个为应用程序.设备.系统等植入管理功能的框架.JMX可以 ...
- 今天讲座的感悟--java
发现当你擅长于某一专业,永远那专业上的人才挤挤.倘若你和相邻专业结合,就能更厉害的走在交叉专业上.例如:医学加计算机等 待续...
- Shell脚本 | 性能测试之CPU占有率
Android 是一个基于 Linux 内核的移动操作系统,Linux 的 CPU 占有率的计算方式也可以应用到 Android App 上. 今天分享的这个脚本的功能,是在多核情况下计算进程的 CP ...
- MongoDB 日志切割三种方式
MongoDB 日志切割 MongoDB 默认是不会进行切割日志的,除非我们配置了 logRotate = rename,并且重启 MongoDB 服务,才会进行切割日志的,那么为了避免实际中我们 ...