9.1创建和使用类

1.创建Dog类
根据Dog 类创建的每个实例都将存储名字和年龄。
我们赋予了每条小狗蹲下(sit() )和打滚(roll_over() )的能力:

class Dog():
    #一次模拟小狗的简单尝试
    def _init_(self,name,age):
        self.name=name
        self.age=age

    def sit(self):
        print(self.name.title()+'is now sitting')


    def roll_over(self):
        print(self.name.title()+' is rolling')

①方法 __init __()
//注意是双下划线
每当你根据Dog类创建新实例的时候,就会运行_init _()。
在这个方法的名称中,开头和末尾各有两个下划线,这是一种约定,旨在避免Python默认方法与普通方法发生名称冲突。

Q为何必须在方法定义中包 含形参self 呢?
每个与类相关联的方法调用都自动传递实参self ,它是一个指向实例本身 的引用,让实例能够访问类中的属性和方法。

我们创建Dog 实例时,Python将调用Dog 类的方法__init__() 。我们将通过实参向Dog() 传递名字和年龄;self 会自动传递,因此不需要传递它。

每当我们根据Dog 类创建实例时,都只需给最后两个形参(name 和age )提供值。

2.根据类 创建实例

class Dog():
 #一次模拟小狗的简单尝试
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def sit(self):
        print(self.name.title()+'is now sitting')


    def roll_over(self):
        print(self.name.title()+' is rolling')

my_dog=Dog('white',6)

print("My dog's name is "+my_dog.name.title()+'.')
print('My dog is '+str(my_dog.age)+' years old.')

运行结果:

python制作小狗 用python画小狗_python制作小狗


方法__init__() 并未显式地包含return 语句, 但Python自动返回一个表示这条小狗的实例。我们将这个实例存储在变量my_dog 中。

①访问属性
语法: 实例名.属性名
eg.: my_dog.name

②调用方法
语法: 实例名.方法名
eg: my_dog.sit()

③创建多个实例
在这里再创建一个your_dog实例。

class Dog():
 #一次模拟小狗的简单尝试
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def sit(self):
        print(self.name.title()+'is now sitting')


    def roll_over(self):
        print(self.name.title()+' is rolling')

my_dog=Dog('white',6)
your_dog=Dog('rourou',3)

print("My dog's name is "+my_dog.name.title()+'.')
print('My dog is '+str(my_dog.age)+' years old.')
my_dog.sit()

print("Your dog's name is "+your_dog.name.title()+'.')
print('Your dog is '+str(your_dog.age)+' years old.')
your_dog.sit()

练习
1.餐馆 :创建一个名为Restaurant 的类,其方法__init__() 设置两个属性:restaurant_name 和cuisine_type 。创建一个名 为describe_restaurant() 的方法和一个名为open_restaurant() 的方法,其中前者打印前述两项信息,而后者打印一条消息,指出餐馆正在营业。

class Restaurant():
    def __init__(self,name,cuisine_type):
        self.name=name
        self.cuisine_type=cuisine_type

    def describe_restaurant(self):
        print("The restaurant's name is "+self.name.title()+'.')
        print("The cuisine_type of this restaurant is "+self.cuisine_type)

    def open_restaurant(self):
        print(self.name.title()+' is open')

my_restaurant=Restaurant('xiaolongkan','sichuan')
my_restaurant.describe_restaurant()
my_restaurant.open_restaurant()

运行结果:

python制作小狗 用python画小狗_User_02


2. 三家餐馆 :根据你为完成练习9-1而编写的类创建三个实例,并对每个实例调用方法describe_restaurant() 。

class Restaurant():
    def __init__(self,name,cuisine_type):
        self.name=name
        self.cuisine_type=cuisine_type

    def describe_restaurant(self):
        print("The restaurant's name is "+self.name.title()+'.')
        print("The cuisine_type of this restaurant is "+self.cuisine_type)

    def open_restaurant(self):
        print(self.name.title()+' is open')

my_restaurant=Restaurant('xiaolongkan','sichuan')
your_restaurant=Restaurant('machimachi','dessert')
his_restaurant=Restaurant('nanjingdapaidang','nanjing food')


my_restaurant.describe_restaurant()
your_restaurant.describe_restaurant()
his_restaurant.describe_restaurant()

my_restaurant.open_restaurant()
your_restaurant.open_restaurant()
his_restaurant.open_restaurant()

3.用户 :创建一个名为User 的类,其中包含属性first_name 和last_name ,还有用户简介通常会存储的其他几个属性。在类User 中定义一个名 为describe_user() 的方法,它打印用户信息摘要;再定义一个名为greet_user() 的方法,它向用户发出个性化的问候。
创建多个表示不同用户的实例,并对每个实例都调用上述两个方法。

class User():
    def __init__(self,first_name,last_name,location):
        self.first_name=first_name
        self.last_name=last_name
        self.location=location

    def describe_user(self):
        name=self.first_name+self.last_name
        print('hello,'+name)
        print('Hope u hava a goog time in '+self.location)

user=User('ming','jing','ningbo')
user.describe_user()

运行结果:

python制作小狗 用python画小狗_重置_03

9.2使用类和实例

1.编写一个表示汽车的类
car.py

class Car():
    def __init__(self,make,model,year):
        self.make=make
        self.model=model
        self.year=year

    def get_descriptive_nmae(self):
        long_name=str(self.year)+' '+self.make+''+self.model
        return long_name.title()


my_new_car=Car('audi','a4',2020)
print(my_new_car.get_descriptive_name())

2.给属性指定默认值

下面来添加一个名为odometer_reading 的属性,其初始值总是为0。我们还添加了一个名为read_odometer() 的方法,用于读取汽车的里程表:

class Car():
    def __init__(self,make,model,year):
        self.make=make
        self.model=model
        self.year=year
        self.odometer_reading=0

    def get_descriptive_name(self):
        long_name=str(self.year)+' '+self.make+''+self.model
        return long_name.title()

    def read_odometer(self):
        print('This car has '+str(self.odometer_reading)+' miles on it')


my_new_car=Car('audi','a4',2020)
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer()
9.3修改属性的值

1.直接修改
在上面car.py 的例子中直接赋值:
my_new_car.odometer_reading=200

class Car():
    def __init__(self,make,model,year):
        self.make=make
        self.model=model
        self.year=year
        self.odometer_reading=0

    def get_descriptive_name(self):
        long_name=str(self.year)+' '+self.make+''+self.model
        return long_name.title()

    def read_odometer(self):
        print('This car has '+str(self.odometer_reading)+' miles on it')


my_new_car=Car('audi','a4',2020)
print(my_new_car.get_descriptive_name())

my_new_car.odometer_reading=200
my_new_car.read_odometer()

2.通过方法修改属性的值
增加了update_odometer()方法

class Car():
    def __init__(self,make,model,year):
        self.make=make
        self.model=model
        self.year=year
        self.odometer_reading=0

    def get_descriptive_name(self):
        long_name=str(self.year)+' '+self.make+''+self.model
        return long_name.title()

    def read_odometer(self):
        print('This car has '+str(self.odometer_reading)+' miles on it')

    def update_odometer(self,mileage):
        self.odometer_reading=mileage


my_new_car=Car('audi','a4',2020)
print(my_new_car.get_descriptive_name())

my_new_car.update_odometer(200)
my_new_car.read_odometer()

运行结果

python制作小狗 用python画小狗_sed_04


可对方法update_odometer() 进行扩展,使其在修改里程表读数时做些额外的工作。下面来添加一些逻辑,禁止任何人将里程表读数往回调:

def update_odometer(self,mileage):
        if mileage>=self.odometer_reading:
            self.odometer_reading=mileage
        else:
            print('you cannot roll back an odometer')

3.通过方法对属性的值进行递增
增加了方法increment_odometer()
这个方法接受了miles,即新增的公里数。
将它加到odometer_reading中
最后调用read_odometer()方法读取该二手车跑的公里数

class Car():
    def __init__(self,make,model,year):
        self.make=make
        self.model=model
        self.year=year
        self.odometer_reading=0

    def get_descriptive_name(self):
        long_name=str(self.year)+' '+self.make+''+self.model
        return long_name.title()

    def read_odometer(self):
        print('This car has '+str(self.odometer_reading)+' miles on it')

    def update_odometer(self,mileage):
        if mileage>=self.odometer_reading:
            self.odometer_reading=mileage
        else:
            print('you cannot roll back an odometer')

    def increment_odometer(self,miles):
        self.odometer_reading+=miles


my_used_car=Car('subaru','outback',2013)
print(my_used_car.get_descriptive_name())

my_used_car.update_odometer(23500)
my_used_car.read_odometer()

my_used_car.increment_odometer(100)
my_used_car.read_odometer()

运行结果:

python制作小狗 用python画小狗_python_05


练习

1.就餐人数:在为完成练习9-1而编写的程序中,添加一个名为number_served 的属性,并将其默认值设置为0。根据这个类创建一个名为restaurant 的实 例;打印有多少人在这家餐馆就餐过,然后修改这个值并再次打印它。

添加一个名为set_number_served() 的方法,它让你能够设置就餐人数。调用这个方法并向它传递一个值,然后再次打印这个值。

添加一个名为increment_number_served() 的方法,它让你能够将就餐人数递增。调用这个方法并向它传递一个这样的值:你认为这家餐馆每天可能接待的就 餐人数。

class Restaurant():
    def __init__(self,name,cuisine_type):
        self.name=name
        self.cuisine_type=cuisine_type
        number_served=0

    def describe_restaurant(self):
        print("The restaurant's name is "+self.name.title()+'.')
        print("The cuisine_type of this restaurant is "+self.cuisine_type)

    def open_restaurant(self):
        print(self.name.title()+' is open')

    def set_number_served(self,number):
        self.number_served=number
        print('就餐人数:'+str(self.number_served))

    def increment_number_served(self,increment):
        self.number_served+=increment
        print('新增后的就餐人数:'+str(self.number_served))
        

my_restaurant=Restaurant('xiaolongkan','sichuan')
my_restaurant.describe_restaurant()
my_restaurant.open_restaurant()

my_restaurant.set_number_served(100)
my_restaurant.increment_number_served(20)

运行结果:

python制作小狗 用python画小狗_python_06


2.尝试登录次数 :在为完成练习9-3而编写的User 类中,添加一个名为login_attempts 的属性。编写一个名为increment_login_attempts() 的方法, 它将属性login_attempts 的值加1。

再编写一个名为reset_login_attempts() 的方法,它将属性login_attempts 的值重置为0。

根据User 类创建一个实例,再调用方法increment_login_attempts() 多次。打印属性login_attempts 的值,确认它被正确地递增;然后,调用方 法reset_login_attempts() ,并再次打印属性login_attempts 的值,确认它被重置为0。

class User():
    def __init__(self,first_name,last_name,location):
        self.first_name=first_name
        self.last_name=last_name
        self.location=location
        self.login_attempts=0

    def describe_user(self):
        name=self.first_name+self.last_name
        print('hello,'+name)
        print('Hope u hava a goog time in '+self.location)

    def increment_login_attempts(self):
        self.login_attempts+=1
        print('用户尝试登陆次数:'+str(self.login_attempts))

    def reset_login_attempts(self):
        self.login_attempts=0
        print('重置用户尝试登陆次数:'+str(self.login_attempts))
        

user=User('ming','jing','ningbo')
user.describe_user()

user.increment_login_attempts()
user.increment_login_attempts()
user.increment_login_attempts()
user.increment_login_attempts()

user.reset_login_attempts()

运行结果:

python制作小狗 用python画小狗_重置_07