一些关于自己学习Python的经历的内容,遇到的问题和思考等,方便以后查询和复习。
声明:本人学习是在扇贝编程通过网络学习的,相关的知识、案例来源于扇贝编程。如果使用请说明来源。
练习:类的创建和调用
我们接着用上一节中创建的类来进行实例化,并调用其中的属性和方法。
要求:
实例化 Bird 类;
访问属性 wings 并打印出 我有 2 只翅膀;
调用方法 fly()。
class Bird:
wings = 2
def fly(self):
print('我会飞')
bird = Bird()
print('我有' + str(bird.wings) +'只翅膀')
bird.fly()
我们来给之前的 Bird 类添加一个 intro 方法。
要求:
添加一个名为 intro 的方法;
intro() 方法里先访问 wings 属性打印出 我有 2 只翅膀,再调用 fly() 方法打印出 我会飞。
class Bird:
wings = 2
def fly(self):
print('我会飞')
def intro(self):
print('我有%d只翅膀%s' % (self.wings))
#后面要调用,前面要定义,最初我把这些放在了fly的print里面了。
self.fly()
bird = Bird()
bird.intro() #这里实例化之后调用intro,所以前面要先定义。
这样是正确的。
但是如果下面这样
class Bird:
wings = 2
def fly(self):
print('我会飞')
def intro(self):
print('我有%d只翅膀%s' % (self.wings, self.fly()))
bird = Bird()
bird.intro()
就会报错:
我会飞
我有2只翅膀None
我会飞,打在上一行了
而且第二行没有打出我会飞,而是返回一个none
原因是使用self.fly()调用前面定义的的fly这个方法的时候,直接的就打出来我会飞,所以我会飞出现在第一行中
而在intro中使用self.fly(),它没有任何数据,原因就是前面的print打印之后不返回任何信息。所以只打出一个none
把前面的fly方法中,print改成return,之后,能打出符合要求的结果,但是不知道这样对不对,是不是符合方法的定义和要求。
class Bird:
wings = 2
def fly(self):
return('我会飞') #这样符不符合方法的定义和要求呢?
def intro(self):
print('我有%d只翅膀%s' % (self.wings, self.fly()))
bird = Bird()
bird.intro()
结果符合要求:
我有2只翅膀
我会飞
但是:把下面这句中的%改成format又出现问题
print('我有%d只翅膀%s'.format (self.wings, self.fly()))
我有%d只翅膀%s
为什么占位符没有换掉相应的数据呢?
改一下占位符,就可以了
print('我有{}只翅膀{}'.format(self.wings, self.fly()))
需要复习一下%和.format的差别,这两个都是个格式化,我记得是对等的。
把前面方法中的return改回print之后,self.fly放在下一个行,单独调用:
print('我有{}只翅膀'.format(self.wings))
self.fly()
或者是:
def fly(self):
print('我会飞')
def intro(self):
print('我有%s只翅膀'%(self.wings))
self.fly()
练习:赛亚人kakarotto
赛亚人(Saiyan) 是日本动漫《七龙珠》中的一个种族的名称。他们来自贝吉塔行星,赛亚人是战斗民族,天生好战,性格暴躁。赛亚人在月圆之夜看到月亮会变成巨猿,变身后是常态的 10 倍左右,并会失去理智。
《七龙珠》的主角孙悟空(本名卡卡罗特)就是被传送到地球的赛亚人,接下来我们创建一个赛亚人类,然后实例化一个卡卡罗特(kakarotto)。
要求:
定义一个名为 Saiyan(赛亚人)的类;
给 Saiyan 类添加 born_place(出身地)属性,值为 贝吉塔行星;
给 Saiyan 类添加 character(性格) 属性,值为 天生好战性格暴躁;
给 Saiyan 类添加 transform()(变身)方法, 作用是打印 变身巨猿;
实例化 Saiyan 类并调用其中的方法或属性。
class Saiyan:
born_place = '贝吉塔行星'
character = '天生好战性格暴躁'
def transform(self):
print('变身巨猿')
saiyan = Saiyan()
print('赛亚人来自%s,并且%s。'%(saiyan.born_place, saiyan.character))
赛亚人来自贝吉塔行星,并且天生好战性格暴躁。
题目要求实例化为卡卡罗特。
class Saiyan:
born_place = '贝吉塔行星'
character = '天生好战性格暴躁'
def transform(self):
print('变身巨猿')
kakarotto = Saiyan()
print('kakarotto是赛亚人来自%s,并且%s。'%(kakarotto.born_place, kakarotto.character))
加上intro,这个应该是自我介绍单词的简写,用来增加可读性,介绍人物或事物。用其他字母或字母组合也可以,比如都换成a,这里是为了增加可读性
class Saiyan: # 定义类的时候,前面的class不用首字母大写。类名称要首字母大写
born_place = '贝吉塔行星'
character = '天生好战性格暴躁'
def transform(self):
return('变身巨猿')
def intro(self):
print('kakarotto是赛亚人来自%s,并且%s。'%(self.born_place, self.character))
print('他在月圆之夜看见月亮会%s' %self.transform())
#前面用return,这里可以打出来,如果前面用print,前面会打一遍,这里结果是none
self.transform()
#这里是调用前面的方法,如果前面用的是return这里没有内容,前面用print,这里才有内容
kakarotto = Saiyan()
kakarotto.intro()
学习笔记
类与实例
编程与生活是相通的,我们生活中把事物按 类 划分,比如人类、狗类、动物类、植物类等。在编程世界里,同样也分了很多 类,比如字符串、整数、浮点数等
在 Python 中 类 是无数个相似个体的集合,其中的每个个体叫做 实例。
类的创建
我们以人类来举例,人类都有哪些共同点呢?两条胳膊、两条腿、直立行走、有着各种颜色的头发、说着各式各样的语言等。这些共同点分为两类:
特征:两条胳膊、两条腿、有着各种颜色的头发 #属性
行为:直立行走、说着各式各样的语言 #方法
在 Python 的类中,我们把这种特征和行为分别称为 属性(attribute)和 方法(method)。现实生活中的“类”是我们归纳总结出来的,而 Python 中的类需要我们自行创建。接下来我们看看如何创建一个类。
定义时,class不用大写首字母,类的名称要首字母大写,后面还要有英文冒号
其下内容都要缩进两个空格
特征直接赋值,值可以直接是数值,也可以是字符串
方法用def定义,和定义函数类似,第一个参数一定是self。方法的执行过程用print,不知道能不能用return。
类的 属性 的创建和变量的定义是一样的,类的 方法 的创建和函数的定义也很类似。唯一不同的是:类的 方法 中有个必须放在首位的参数 self,它表示创建的实例本身。
除此之外,按照命名规范,类名的首字母要大写,以便我们可以轻松地辨认出这是个类。
类的调用
我们刚才只是创建了类,接下来我们看看怎么使用创建好的 属性 和 方法!
class Human:
arms = 2
legs = 2
hair = '各种颜色的头发'
def walk(self):
print('直立行走')
def speak(self):
print('说着各式各样的语言')
# 类的实例化
human = Human()
print(human.arms)
# 输出:2
print(human.legs)
# 输出:2
print(human.hair)
# 输出:各种颜色的头发
human.walk()
# 输出:直立行走
human.speak()
# 输出:说着各式各样的语言
human = Human() 这一行代码非常关键,通过该类创建了一个类的实例对象,这个过程叫做 类的实例化。
print(human)
# 输出:<__main__.Human object>
print(type(human))
# 输出:
<__main__.Human object> 表明这是一个 Human 类的实例对象(object),
当我们实例化后得到实例 human 后,实例 human 就拥有了 Human 类的所有 属性 和 方法。然后我们通过 实例名.属性名 和 实例名.方法名 去调用它们。
为什么调用方法时不用传参数呢?定义方法的时候不是有个参数 self 吗?这其实是 self 的特殊之处:定义方法的时候必须有,调用方法的时候要忽略。
我们总结一下进行类的调用的步骤:
创建一个类; class Human: 定义的时候,类名称后面没有括号和参数
进行类的实例化; human = Human() 实例化时类后面要加上括号,前面用其他字母也可
通过类的实例调用类的属性和方法。 human.legs,human.walk() 调用是前要加上实例名,但是方法名后面只有括号,里面没有参数。
练习:创建类和调用
我们接着用上一节中创建的类来进行实例化,并调用其中的属性和方法。
要求:
实例化 Bird 类;
访问属性 wings 并打印出 我有 2 只翅膀;
调用方法 fly()。
class Bird:
wings = 2
def fly(self):
print('我会飞')
bird = Bird()
print('我有' + str(bird.wings) +'只翅膀')
bird.fly()
答案中结果的输出是用格式化,直接用实例名+特征名调用。
self 的作用
self 在英文中是“自己、自我”的意思,在 Python 的类中,self 表示创建的实例本身。
class Human:
arms = 2
legs = 2
hair = '各种颜色的头发'
def walk(self):
print('直立行走')
def speak(self):
print('说着各式各样的语言')
def intro(self):
# 类的方法里访问类的属性
print('人类有%d条胳膊%d条腿' % (arms, legs))
# 报错:NameError: name 'arms' is not defined on line 14
# 类的实例化
human = Human()
human.intro()
在类的方法里访问类的属性时,发现出现了变量未定义的错误!说明在类的方法里直接访问类的属性是不行的,那要怎么办呢?前文说过,访问类的属性要先实例化,然后通过 实例名.属性 进行访问。
但在类的方法内访问类的属性时,类的实例还没被创建。这时,self 就出现了,它的作用是代替实例本身,所以上面的例子正确的写法应该是这样:
class Human:
arms = 2
legs = 2
hair = '各种颜色的头发'
def walk(self):
print('直立行走')
def speak(self):
print('说着各式各样的语言')
def intro(self):
# 类的方法里访问类的变量
print('人类有%d条胳膊%d条腿' % (self.arms, self.legs))
# 类的实例化
human = Human()
human.intro()
# 输出:人类有2条胳膊2条腿
当执行 human.intro() 这行代码时,Python 会将 human 作为第一个参数偷偷传递给 self,这样我们就不再需要传入第一个参数,并能通过 self 访问类的属性和方法了。
class Human:
arms = 2
legs = 2
def intro(self):
print('人类有%d条胳膊%d条腿' % (self.arms, self.legs))
human = Human() 实例化的时候,后面不用冒号
human.intro()
# 输出:人类有2条胳膊2条腿