编程小白 问关于python当中类的方法的参数问题
欧阳克
欧阳克 2017-06-22 11:52:02
0
4
924

代码如下:

# -*- 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()

执行结果:

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

结果反而运行出错:

为什么会这样?

欧阳克
欧阳克

温故而知新,可以为师矣。 博客:www.ouyangke.com

全部回复(4)
巴扎黑

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

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

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

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

三叔

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

不一定非要 self

为情所困

雷雷

Ty80
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_typeFactory.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是怎么工作的,要不然是写不好这类代码的。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!