您的位置:首页技术文章
文章详情页

编程小白 问关于python当中类的方法的参数问题

【字号: 日期:2022-06-28 09:15:46浏览:72作者:猪猪

问题描述

代码如下:

# -*- coding:gb2312 -*-class CarStore(object): def order(self,car_type):return Factory.select(car_type)class Factory(object): def select(car_type): #为什么这个地方的方法,没有self参数也可以运行?if car_type == '索纳塔': return Suonata()elif car_type == '名图': return Mingtu()else: print('没有您要的车型!')class Car(object): def move(self):print('车在移动...') def music(self):print('正在播放音乐...') def stop(self):print('车在停止...')class Suonata(Car): def __init__(self):print('索纳塔')class Mingtu(Car): def __init__(self):print('名图')car_store = CarStore()suonata = car_store.order('索纳塔')#car.move()#car.music()#car.stop()suonata.move()

执行结果:

编程小白 问关于python当中类的方法的参数问题

这段代码本身是没有问题,可以执行的。我的疑问是,为什么第七行代码def select(car_type): 这个地方明明没有self,也可以执行?我记得我在学类的时候,被教育实例方法里面每个方法都必须加上一个self的参数,这里居然没有,然后我在这个地方加上了self反而出错了,如下图:编程小白 问关于python当中类的方法的参数问题

结果反而运行出错:

编程小白 问关于python当中类的方法的参数问题

为什么会这样?

问题解答

回答1:

你是不是用的python3?在python3中,如果成员函数不加self,则代表该函数是静态成员函数,可以直接使用“类名.函数名(参数)”的形式直接调用。但是如果你加了self,则这个函数为类的成员函数,在其他调用类中必须这样调用:“类名.函数名(self,参数)”,或者在调用类类中实现一个实例,“实例名.函数名(参数)。

python3是上述这样,我的测试,在python2中不是。

你在select函数中加了self,但是在 CarStore::order()中调用却使用“类名.函数名(参数)”的形式,所以不正确。你在CarStore::order()调用时改为“类名.函数名(self,参数)”或者在CarStore::order()实现一个实例,使用“实例名.函数名(参数)“这样的形式试试。

昨晚看到的,太晚了,所以今天早上测试的。

回答2:

self 不是魔法,改成什么名字都可以的

不一定非要 self

回答3:

4 return Factory.select(self, car_type)回答4:

class Factory(object): def select(car_type):if car_type == '索纳塔': return Suonata()elif car_type == '名图': return Mingtu()else: print('没有您要的车型!')

按这个写法,select是对象方法,调用需要关联一个实例Factory()。调用时对象实例是与第一个参数car_type绑定。这个参数名一般约定为self但是,不要求。

你需要明白以下两种调用方式是不同的:

f = Factory()f.select(xxx)Factory.select(xxx)

第一种方式,用实例对象去调用,第一个参数car_type自动与实例对象f绑定;第二种方式,用类去调用,第一个参数(car_type)没有绑定;你需要自己绑定才能不出错——也就是你传进去的car_type:Factory.selct(car_type)这行。

但是,当你加上self后,这个函数有两个参数,但是你只绑定了car_type,也就是绑定到第一个参数self,第二个没有值,必然就出错了。

这里你要做的其实是将select实现成类方法:

class Factory(object): @classmethod def select(cls, car_type):if car_type == '索纳塔': return Suonata()elif car_type == '名图': return Mingtu()else: print('没有您要的车型!')

那么,以Factory.select(car_type)调用时,cls自动绑定到Factory,而car_type则绑定到car_type。

以上,无论是self还是cls,都只是约定的名字而已,起作用的是Python的类-对象-方法模型。

建议可以看看《Python源码剖析》,至少要理解@classmethod是怎么工作的,要不然是写不好这类代码的。

标签: Python 编程
相关文章: