Python学习笔记(4)类

Chapter 9

  • 例子(适用于Python3)
class Dog():
    """一次模拟小狗的简单尝试"""
    def __init__(self, name, age):
        """初始化属性name与age"""
        self.name = name
        self.age = age
        self.height = 0

    def sit(self):
        """模拟小狗蹲下"""
        print(self.name.title() + " is now sitting.")

    def roll_over(self):
        """模拟小狗打滚儿"""
        print(self.name.title() + " is rolling over!")

my_dog = Dog('willie', 5)
print("My dog's name is " + my_dog.name + ", and he is " + 
    str(my_dog.age) + " years old.")
my_dog.sit()
my_dog.roll_over()

注意:
1. class Dog()Python中,根据约定,首字母大写的名称指的是类。
2. __init__类似于C++中的构造函数。为了与其他函数区分,其名称__init__不可改变,且前后分别有两个下划线。每次用Dog类实例化时,都会自动运行这个函数。另外,Python的类中的函数,被称为方法
3. self相当于C++中的this,只不过C++中是隐性的,Python中是显性的。Python的类中,所有方法的形参都有self不能省略。 另外,在每个方法中,self还必须位于其他形参的前面。不过,它的传递会自动完成。因此,我们在传入参数时直接忽略它就好。
4. self.nameself为前缀的变量,可以在类的所有方法中使用。我们还可以通过类的任意实例来访问它们。我们把像这样可以用实例访问的变量,成为属性。注意,类中的每个属性都应该有初始值,即使它是0或空字符串。在方法__init__()中指定初始值是可行的。如果对某个属性这样做了,就无须包含相应形参,例如,本例中的self.height
5. my_dog = Dog('willie', 5)此时,会自动调用__init__方法。该方法虽然没有显式地写上return,但会自动返回一个实例。
6. my_dog.sit()创建实例后,我们就可以使用句点来调用类中的任意方法。需要注意,调用方法时,一定要写上后面的括号(),否则会出现意料之外的结果(例如,<bound method ElecDog.battery_info of <__main__.ElecDog object at 0x101d5c908>>)。

  • 修改属性的值

直接修改属性的值

class Dog():
         --snip--

--snip--
my_dog.name = "Lucky"
#注意:可以修改任何属性的值,即使它们曾经出现在__init__的形参里。

通过方法修改属性的值

class Dog():
         --snip--

        def change_name(self, new_name):
            self.name = new_name

--snip--
my_dog.change_name("Lucky")
  • 继承
class Dog():
    """一次模拟小狗的简单尝试"""

    def __init__(self, name, age):
        """初始化属性name与age"""
        self.name = name
        self.age = age
        self.height = 0

    def sit(self):
        """模拟小狗蹲下"""
        print(self.name.title() + " is now sitting.")

    def roll_over(self):
        """模拟小狗打滚儿"""
        print(self.name.title() + " is rolling over!")

class ElecDog(Dog):
    """继承Dog()类的电子狗类"""
    def __init__(self, name, elec_age, battery_size):
        """还要初始化父类"""
        super().__init__(name, elec_age)
        self.battery = battery_size

    def battery_info(self):
        """返回电池容量"""
        return(self.battery)


my_e_dog = ElecDog("Lucky", 5, 10000)
print("My dog's name is " + my_e_dog.name + ", and he is " + 
    str(my_e_dog.age) + " years old.")
my_e_dog.sit()
my_e_dog.roll_over()
print("Battery size is " + str(my_e_dog.battery_info()) + ".")

注意:
1. 创建子类时,父类必须在当前文件中,而且位于子类的前面。
2. ElecDog(Dog)定义子类时,必须在括号里指明父类的名称。
3. siper().__init_(name, elec_age)其中,super()是一个特殊的函数,将子类与父类连接起来。这行代码让子类调用父类的方法__init__(),用子类的形参初始化父类,让子类包含父类的所有属性。因为父类也被称为超类superclass,该函数因此得名。
4. self.battery = battery_size先初始化父类的属性,而后才初始化子类特有的属性。
5. 对于父类中的方法,如果它不符合子类的需求,子类可以将其重写。只需写一个同名方法即可。这样,实例化子类时,Python就不会考虑父类方法,而是只看子类定义中的相应方法。

  • 将实例用作属性。类似于,C++中,将类作为另一个类的成员。
# class Dog():
#     """一次模拟小狗的简单尝试"""

#     def __init__(self, name, age):
#         """初始化属性name与age"""
#         self.name = name
#         self.age = age
#         self.height = 0

#     def sit(self):
#         """模拟小狗蹲下"""
#         print(self.name.title() + " is now sitting.")

#     def roll_over(self):
#         """模拟小狗打滚儿"""
#         print(self.name.title() + " is rolling over!")

class Battery():
    """对电池的简单模拟"""
    def __init__(self, battery_size=10000):
        """初始化"""
        self.size = battery_size

    def show_size(self):
        """显示电池容量"""
        return self.size


class ElecDog(Dog):
    """继承Dog()类的电子狗类"""
    def __init__(self, name, elec_age, battery_size):
        """还要初始化父类"""
        super().__init__(name, elec_age)
        self.battery = Battery(battery_size)


# my_e_dog = ElecDog("Lucky", 5, 9999)
# print("My dog's name is " + my_e_dog.name + ", and he is " + 
#     str(my_e_dog.age) + " years old.")
# my_e_dog.sit()
# my_e_dog.roll_over()

print("Battery size is " + str(my_e_dog.battery.show_size()) + ".")
  • 导入类

导入单个类注意,当我们需要实例化一个子类的时候,只需要把子类和父类放在同一个文件里,再只导入子类即可。如果子类和父类在两个不同的文件中,则需要都导入进来(两个import)。

from car import Elec_car

从一个模块中导入多个类用逗号隔开。

from car import Car, Elec_car

导入整个模块倘若如此,则使用其中的每一个类的时候,都应该用句点。这样也能避免重名带来的一些问题。

import car

导入模块中的所有类使用星号。但是,不推荐这种方式,原因与不推荐导入一个模块中的所有函数的原因类似。

from car import *
  • Python标准库。下面的例子中,展示了利用标准库来实现记录了键-值对添加顺序的字典的方法。
from collections import OrderedDict

favorite_languages = OrderedDict()

favorite_languages['jen'] = 'python'
favorite_languages['sarah'] = 'c' 
favorite_languages['edward'] = 'ruby' 
favorite_languages['phil'] = 'python'

for name, language in favorite_languages.items(): 
    print(name.title() + "'s favorite language is " +
        language.title() + ".")

另外,模块random包含以各种方式生成随机数的函数。其中的randint(int_1, int_2)返回满足int_1 <= x <= int_2的整数。

from random import randint

print( randint(1, 6)  )


  • 规范

注意:
类名采用驼峰命名法。即,类名中,每个单词的首字母都大写,并且不使用下划线。
实例名模块名采用小写,并且单词之间使用下划线。
每个类都要有文档字符串,对类的功能进行简单描述。每个模块也要有,对其中包含了什么类进行简单描述。
在类中,用一个空行区分方法。在模块中,用两个空格区分类。
先导入标准库中的模块,再导入自己编写的模块。两者之间,用一个空行隔开。

猜你喜欢

转载自blog.csdn.net/twllx/article/details/75141529