什么是“self”
python的shell其实就是”c++“中的“this”指针。
“类”是图纸,经过实例化后的对象才能用。“self”相当于每个实例化后对象的门牌号,因为每一个类可以实例化很多对象,这些对象都是来源于一个类。当一个对象的方法被调用的时候,对象会将自身作为第一个参数传给“self”参数,接收到“self”参数时,python就知道是哪一个对象在调用方法。
看下面的例子:
`>>> class Ball:
def setName(self,name):
self.name = name
def kick(self):
print("我叫%s,我被踢了...."% self.name)
>>> a = Ball()
>>> b = Ball()
>>> c = Ball()
>>> a.setName("球A")
>>> b.setName("球B")
>>> c.setName("球C")
>>> a.kick()
我叫球A,我被踢了....
>>> b.kick()
我叫球B,我被踢了....
>>> c.kick()
我叫球C,我被踢了....
>>>
可以看出类,每个对象调用kick方法时候,由于“self”的存在,python就知道是谁在调用kick()函数。
__init__(self)
这是python的魔法方法,这玩意其实就是c++中的“构造函数”
先看下面:
>>> class Ball:
def __init__(self,name):
self.name = name
def kick(self):
print("我叫%s,我被踢了..." % self.name)>>> b = Ball("小龟")
>>> b.kick()
我叫小龟,我被踢了...
>>>
只要调用 Ball()进行对象实例化,就必须制定对象的名称,因为会默认调用 “__init__(self,name)”
共有和私有
python的属性和方法都是共有的,可以使用“.”调用。
在python中定义私有变量,只需要在变量或函数名前加上“__”双下划线,这样,这个个变量,函数就是私有的。
举个例子
>>> class Person:
__name = "小龟龟"
下面直接调用
>>> p = Person()
>>> p.name
Traceback (most recent call last):
File "<pyshell#36>", line 1, in <module>
p.name
AttributeError: 'Person' object has no attribute 'name'>>> p.__name
Traceback (most recent call last):
File "<pyshell#37>", line 1, in <module>
p.__name
AttributeError: 'Person' object has no attribute '__name'
报错了,因为name是私有的
有两种方法可以实现
第一种方法:
_类型__变量名
>>> class Person:
__name = "小龟龟"
>>> p = Person()
>>> p._Person__name
'小龟龟'
第二中方法:
>>> class Person:
__name = "小龟龟"
def getName(self):
return self.__name>>>
>>> p = Person()
>>> p.getName()
'小龟龟'
可见,python中的私有变量是“伪私有”
★finished by songpl,2019.1.5
继续
课后题https://fishc.com.cn/thread-48620-1-2.html
0. 下面的代码体现了面向对象的什么特征?
>>> "FishC.com".count('o')
1
>>> [1, 1, 2, 3, 5, 8].count(1)
2
>>> (0, 2, 4, 8, 12, 18).count(1)
0
答:体现了面向对象的编程的多态特征。多态:多态就是不同对象对同一方法有不同的响应。
1. 当一个程序员不想把同一段代码写几次,他们发明了函数解决这种情况。当程序员已经有一个类,而向建立一个非常相近的类,他们会怎么做?
答:继承。他们会定义一个新类,继承已有的这个类,只需要在新类中添加和重新需要的方法就行。
例如,已有一个龟类,那么如果我们要定义一个甲鱼类,我们只需要让甲鱼类继承已有的龟类,然后重新写壳的属性为“软的”就行。(据说,甲鱼的壳是软的。)
2. self参数的作用是什么。
答:绑定方法,具有有了这个参数,Python再也不会傻傻分不清楚是哪个对象咋调用方法了。你可以认为方法中的self其实就是实例化对象的唯一的标志。
3. 如果我们不希望我们的对象的属性或方法被外部直接引用,我们可以怎么做?
答:我们可以在属性或者方法前面加上双下划线“__”,这种变量和方法是无法直接从外部进行访问的。
4. 实例化对象后那个方法会被自动调用?
答:__init__方法会在实例化时被自动调用,我们称之为魔法方法。你可以重写这个方法,为对象定制初始化方案。
5. 分析下面代码的错误原因:
class Myclass:
name = 'FishC'
def myFun(self):
print("hellow FishC")
>>> Myclass.name
'FishC'
>>> Myclass.myFun()
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
Myclass.myFun()
TypeError: myFun() missing 1 required positional argument: 'self'
>>> myclass = Myclass()
>>> myclass.myFun()
hellow FishC
答:首先应该弄清楚类、类对象、实例对象三个名词的区别。
我们常说的“类”是指的“类定义”,由于“Python无处不对象”,所以当类定义完成之后,就是类对象。这个时候你可以对类的属性(变量)直接进行访问。
一个类可以实例化出无数的对象(实例化对象),python为了区分是哪个实例化对象调用了“方法”,于是要求方法必须绑定(通过self参数)才能调用。而未实例化的类对象直接调用方法,因为缺少self参数,报错!!!
动动手
0. 按照下面的要求:定义一个游乐园门票的类,并计算2个成人+1个小孩平时的票价。
平日票价100元;
周末票价为平日的120%;
儿童半票;
class Ticketprice:
commonprice = 100
weekendsprice = commonprice*1.2
def commomCost(self,num_adult,num_child):
cost = num_adult*self.commonprice + num_child*self.commonprice*0.5
print("平日,%d个成人和%d个儿童的消费是:%d"%(num_adult,num_child,cost))
def weekendsCost(self,num_adult,num_child):
cost = num_adult*self.weekendsprice + num_child*self.weekendsprice*0.5
print("周末,%d个成人和%d个儿童的消费是:%d"%(num_adult,num_child,cost))
运行结果:
>>> ticket = Ticketprice()
>>> ticket.commomCost(2,1)
平日,2个成人和1个儿童的消费是:250
★finished by songpl,2019.1.8