python 类方法 函数_python 类函数,实例函数,静态函数

一、实现方法

classFunction(object):#在类定义中定义变量

cls_variable = "class varibale"

def __init__(self):#在构造函数中创建变量

self.__instance_variable = "instance variable"

definstance_method(self):print(self.cls_variable)print(self.__instance_variable)print("this is a instance method")

@staticmethoddefstatic_method():print(Function.cls_variable)#print(Function.__instance_variable) 此处会报错,无法访问实例变量

print("this is a static method")

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

print("this is a class method")

@classmethoddefset_class_variable(cls):

cls.cls_variable= 'new class variable'

defset_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、函数访问变量中,有很大不同。

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

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

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

4、修改变量的范围

new classvariable

thisis a classmethod

newclassvariable

instance variable

thisisa instance method

newclassvariable

thisis a static method

上图是function1中输出的结果。

new classvariable

thisis a classmethod

newclassvariable

new instance varibale

thisisa instance method

newclassvariable

thisisa static method

newclass variable

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

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

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

二、三者选择原则

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

1、类方法和静态方法

#-*- coding: utf-8 -*-

"""@Time : 2017/12/29 9:50

@Author:dongbl

@Description:"""

classFunction(object):

X= 1Y= 2@staticmethoddef averag(*mixes):return sum(mixes) /len(mixes)

@staticmethoddefstatic_method():#通过function调用,如果类名修改,此处需要修改不太方便

returnFunction.averag(Function.X, Function.Y)

@classmethoddefclass_method(cls):returncls.averag(cls.X, cls.Y)classSubclass(Function):

X=3Y= 5@staticmethoddef averag(*mixes):return sum(mixes) / 3func=Subclass()print(func.static_method())print(func.class_method())

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

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

1.5

2.6666666666666665

上面是两者的输出。

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

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

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

三、类方法和实例方法

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

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

比如我们创建一个类:

classDateTest():def __init__(self,year,month,day):

self.year=year

self.day=day

self.month=monthdefprint_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:"""

classDateTest():def __init__(self,year,month,day):

self.year=year

self.day=day

self.month=monthdefprint_date(self):print("{}:{}:{}".format(self.year,self.month,self.day))

@classmethoddefget_date(cls,string_date):

year,month,day= map(int,string_date.split('-'))returncls(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就行了。

四、参考文献

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值