1.创建和使用类

1.1 创建 Dog 类。根据 Dog 类创建的每个实例都将存储名字和年龄。我们赋予了每条小狗蹲下( sit() )和打滚( roll_over() )的能力:
In [2]:
class Dog():
"""A simple attempt to model a dog.""" def __init__(self, name, age):
"""Initialize name and age attributes."""
self.name = name
self.age = age def sit(self):
"""Simulate a dog sitting in response to a command."""
print(self.name.title() + " is now sitting.") # .title()方法表示首字母大写 def roll_over(self):
"""Simulate rolling over in response to a command."""
print(self.name.title() + " rolled over!")

init() 是一个特殊的方法,每当你根据 Dog 类创建新实例时,Python都会自动运行它。在这个方法的名称中,开头和末尾各有两个下划线,这是一种约定,旨在避免Python默认方法与普通方法发生名称冲突。我们将方法 init() 定义成了包含三个形参: self 、 name 和 age 。在这个方法的定义中,形参 self 必不可少,还必须位于其他形参的前面。为何必须在方法定义中包含形参 self 呢?因为Python调用这个 init() 方法来创建 Dog 实例时,将自动传入实参 self 。每个与类相关联的方法调用都自动传递实参 self ,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。我们创建 Dog 实例时,Python将调用 Dog 类的方法 init() 。我们将通过实参向 Dog() 传递名字和年龄; self 会自动传递,因此我们不需要传递它。每当我们根据 Dog 类创建实例时,都只需给最后两个形参( name 和 age )提供值。

self.name = name 获取存储在形参 name 中的值,并将其存储到变量 name 中,然后该变量被关联到当前创建的实例。 self.age = age 的作用与此类似。像这样可通过实例访问的变量称为属性。

Dog 类还定义了另外两个方法: sit() 和 roll_over() (见)。由于这些方法不需要额外的信息,如名字或年龄,因此它们只有一个形参 self 。我们后面将创建的实例能够访问这些方法,换句话说,它们都会蹲下和打滚。当前, sit() 和 roll_over() 所做的有限,它们只是打印一条消息,指出小狗正蹲下或打滚。

 

1.2 根据类创建实例

In [3]:
my_dog = Dog('willie', 6)
your_dog = Dog('lucy', 3)

我们让Python创建一条名字为 'willie' 、年龄为 6 的小狗。遇到这行代码时,Python使用实参 'willie' 和 6 调用 Dog 类中的方法 init() 。 方法 init() 创建一个表示特定小狗的示例,并使用我们提供的值来设置属性 name 和 age 。方法init() 并未显式地包含 return 语句,但Python自动返回一个表示这条小狗的实例。我们将这个实例存储在变量 my_dog 中。在这里,命名约定很有用:我们通常可以认为首字母大写的名称(如Dog )指的是类,而小写的名称(如 my_dog )指的是根据类创建的实例。

In [4]:
print("My dog's name is " + my_dog.name.title() + ".")
print("My dog is " + str(my_dog.age) + " years old.")
My dog's name is Willie.
My dog is 6 years old.
 

要访问实例的属性,可使用句点表示法。访问 my_dog 的属性name 的值,句点表示法在Python中很常用,这种语法演示了Python如何获悉属性的值。在这里,Python先找到实例 my_dog ,再查找与这个实例相关联的属性 name 。在 Dog 类中引用这个属性时,使用的是 self.name 。

根据 Dog 类创建实例后,就可以使用句点表示法来调用 Dog 类中定义的任何方法。下面来让小狗蹲下和打滚

In [5]:
my_dog.sit()
Willie is now sitting.
 

2.使用类和实例

2.1 下面来编写一个表示汽车的类,它存储了有关汽车的信息,还有一个汇总这些信息的方法:

In [6]:
class Car():
"""A simple attempt to represent a car.""" def __init__(self, manufacturer, model, year):
"""Initialize attributes to describe a car."""
self.manufacturer = manufacturer
self.model = model
self.year = year def get_descriptive_name(self):
"""Return a neatly formatted descriptive name."""
long_name = str(self.year) + ' ' + self.manufacturer + ' ' + self.model
return long_name.title()

我们定义了方法 init() 。与前面的 Dog 类中一样,这个方法的第一个形参为 self ; 我们还在这个方法中包含了另外三个形参: make 、 model 和 year 。方法 init() 接受这些形参的 值,并将它们存储在根据这个类创建的实例的属性中。创建新的 Car 实例时,我们需要指定其制 造商、型号和生产年份。

我们定义了一个名为 get_descriptive_name() 的方法,它使用属性 year 、 make 和 model 创建一个对汽车进行描述的字符串,让我们无需分别打印每个属性的值。为在这个方法中访问属 性的值,我们使用了 self.make 、 self.model 和 self.year 。我们根据 Car 类创建了一个实 例,并将其存储到变量 my_new_car 中。接下来,我们调用方法 get_descriptive_name() ,指出我 们拥有的是一辆什么样的汽车:

In [7]:
my_beetle = Car('volkswagen', 'beetle', 2015)
print(my_beetle.get_descriptive_name())
2015 Volkswagen Beetle
 

2.2 给属性指定默认值

类中的每个属性都必须有初始值,哪怕这个值是0或空字符串。在有些情况下,如设置默认 值时,在方法 init() 内指定这种初始值是可行的;如果你对某个属性这样做了,就无需包含 为它提供初始值的形参。

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

In [8]:
class Car():
"""A simple attempt to represent a car.""" def __init__(self, manufacturer, model, year):
"""Initialize attributes to describe a car."""
self.manufacturer = manufacturer
self.model = model
self.year = year
self.odometer_reading = 0 def get_descriptive_name(self):
"""Return a neatly formatted descriptive name."""
long_name = str(self.year) + ' ' + self.manufacturer + ' ' + self.model
return long_name.title() def read_odometer(self):
"""Print a statement showing the car's mileage."""
print("This car has " + str(self.odometer_reading) + " miles on it.")
 

现在,当Python调用方法 init() 来创建新实例时,将像前一个示例一样以属性的方式存 储制造商、型号和生产年份。接下来,Python将创建一个名为 odometer_reading 的属性,并将其 初始值设置为0。,我们还定义了一个名为 read_odometer() 的方法,它让你能够轻 松地获悉汽车的里程。 一开始汽车的里程为0:

In [9]:
my_new_car = Car('audi', 'a4', 2015)
print(my_new_car.get_descriptive_name())
2015 Audi A4
In [10]:
my_new_car.read_odometer()
This car has 0 miles on it.
 

2.3 修改属性的值

2.3.1 直接修改属性的值。要修改属性的值,最简单的方式是通过实例直接访问它。下面的代码直接将里程表读数设置 为23:

In [11]:
my_new_car.odometer_reading = 23
my_new_car.read_odometer()
This car has 23 miles on it.
 

2.3.2 通过方法修改属性的值。如果有替你更新属性的方法,将大有裨益。这样,你就无需直接访问属性,而可将值传递给 一个方法,由它在内部进行更新。 下面的示例演示了一个名为 update_odometer() 的方法:

In [14]:
class Car():
"""A simple attempt to represent a car.""" def __init__(self, manufacturer, model, year):
"""Initialize attributes to describe a car."""
self.manufacturer = manufacturer
self.model = model
self.year = year
self.odometer_reading = 0 def get_descriptive_name(self):
"""Return a neatly formatted descriptive name."""
long_name = str(self.year) + ' ' + self.manufacturer + ' ' + self.model
return long_name.title() def read_odometer(self):
"""Print a statement showing the car's mileage."""
print("This car has " + str(self.odometer_reading) + " miles on it.") def update_odometer(self, mileage):
"""
Set the odometer reading to the given value.
Reject the change if it attempts to roll the odometer back.
"""
if mileage >= self.odometer_reading:
self.odometer_reading = mileage
else:
print("You can't roll back an odometer!")

对 Car 类所做的唯一修改是在处添加了方法 update_odometer() 。这个方法接受一个里程值, 并将其存储到 self.odometer_reading 中。同时我们添 加一些逻辑,禁止任何人将里程表读数往回调:

In [15]:
my_new_car = Car('audi', 'a4', 2015)
print(my_new_car.get_descriptive_name())
 
2015 Audi A4
In [16]:
my_new_car.update_odometer(25)
my_new_car.read_odometer()
This car has 25 miles on it.
In [17]:
my_new_car.update_odometer(23)
my_new_car.read_odometer()
You can't roll back an odometer!
This car has 25 miles on it.
 

2.3.3 通过方法对属性的值进行递增

 

有时候需要将属性值递增特定的量,而不是将其设置为全新的值。假设我们购买了一辆二手 车,且从购买到登记期间增加了100英里的里程,下面的方法让我们能够传递这个增量,并相应 地增加里程表读数:

In [26]:
"""A class that can be used to represent a car."""

class Car():
"""A simple attempt to represent a car.""" def __init__(self, manufacturer, model, year):
"""Initialize attributes to describe a car."""
self.manufacturer = manufacturer
self.model = model
self.year = year
self.odometer_reading = 0 def get_descriptive_name(self):
"""Return a neatly formatted descriptive name."""
long_name = str(self.year) + ' ' + self.manufacturer + ' ' + self.model
return long_name.title() def read_odometer(self):
"""Print a statement showing the car's mileage."""
print("This car has " + str(self.odometer_reading) + " miles on it.") def update_odometer(self, mileage):
"""
Set the odometer reading to the given value.
Reject the change if it attempts to roll the odometer back.
"""
if mileage >= self.odometer_reading:
self.odometer_reading = mileage
else:
print("You can't roll back an odometer!") def increment_odometer(self, miles):
"""Add the given amount to the odometer reading."""
self.odometer_reading += miles
In [27]:
my_car = Car('tank', '96', 2005)
print(my_car.get_descriptive_name())
2005 Tank 96
In [28]:
my_car.update_odometer(25000)
my_car.read_odometer()
This car has 25000 miles on it.
In [29]:
my_car.increment_odometer(100)
my_car.read_odometer()
This car has 25100 miles on it.
 
 

03python面向对象编程1的更多相关文章

  1. 03python面向对象编程5

    5.1 继承机制及其使用 继承是面向对象的三大特征之一,也是实现软件复用的重要手段.Python 的继承是多继承机制,即一个子类可以同时有多个直接父类. Python 子类继承父类的语法是在定义子类时 ...

  2. 03python面向对象编程4

    http://c.biancheng.net/view/2287.html 1.1定义类和对象 在面向对象的程序设计过程中有两个重要概念:类(class)和对象(object,也被称为实例,insta ...

  3. 03python面向对象编程2

    3.继承 如果你要编写的类是另一个现成类的特殊版本,可使用继承.一个类继承另一个类时,它将自动获得另一个类的所有属性和方法:原有的类称为父类,而新类称为子类.子类继承了其父类的所有属性和方法,同时还可 ...

  4. 03python面向对象编程3

    案例学习 # notebook.pyimport datetime # Store the next available id for all new notes last_id = 0 class ...

  5. angular2系列教程(六)两种pipe:函数式编程与面向对象编程

    今天,我们要讲的是angualr2的pipe这个知识点. 例子

  6. 带你一分钟理解闭包--js面向对象编程

    上一篇<简单粗暴地理解js原型链--js面向对象编程>没想到能攒到这么多赞,实属意外.分享是个好事情,尤其是分享自己的学习感悟.所以网上关于原型链.闭包.作用域等文章多如牛毛,很多文章写得 ...

  7. PHP 面向对象编程和设计模式 (1/5) - 抽象类、对象接口、instanceof 和契约式编程

    PHP高级程序设计 学习笔记 2014.06.09 什么是面向对象编程 面向对象编程(Object Oriented Programming,OOP)是一种计算机编程架构.OOP 的一条基本原则是计算 ...

  8. Delphi_09_Delphi_Object_Pascal_面向对象编程

    今天这里讨论一下Delphi中的面向对象编程,这里不做过多过细的讨论,主要做提纲挈领的描述,帮助自己抓做重点. 本随笔分为两部分: 一.面向对象编程 二.面向对象编程详细描述 ------------ ...

  9. python基础-面向对象编程

    一.三大编程范式 编程范式即编程的方法论,标识一种编程风格 三大编程范式: 1.面向过程编程 2.函数式编程 3.面向对象编程 二.编程进化论 1.编程最开始就是无组织无结构,从简单控制流中按步写指令 ...

随机推荐

  1. vue 中 event.stopPropagation() 和event.preventDefault() 使用

    1.event.stopPropagation()方法 这是阻止事件的冒泡方法,不让事件向document上蔓延,但是默认事件任然会执行,当你掉用这个方法的时候,如果点击一个连接,这个连接仍然会被打开 ...

  2. ES6中对字符串处理的优点

    目录 1.字符的Unicode表示法 2.字符串的遍历接口 3.直接输入 U+2028 和 U+2029(分行符 和 分段符) 4.JSON.stringify() 的改造 1.字符的Unicode表 ...

  3. javascript二叉树

    javascript中的二叉树一(binary tree) 毕业也快2年了,毕业之后就没有认真写过博客了,都是那里学习一下,这里弄一下.学习了也不做笔记,过后就忘记了.我对这种状态打从心里是讨厌的. ...

  4. pycharm 调用turtle模块时,窗口闪屏不能显示

    #如下代码时,在pycharm中运行时,窗口在程序结束后,直接关闭,不能看到绘制的图像. #在python自带的IDE中,在执行代码后,可以看到窗口的显示. import turtle t = tur ...

  5. String2LongUtil

    public class String2LongUtil { /** * String类型转换成date类型 * strTime: 要转换的string类型的时间, * formatType: 要转换 ...

  6. .net framework4.6项目的dll升级后,未找到方法“System.String.GetPathsOfAllDirectoriesAbove”解决

    https://stackoverflow.com/questions/59276192/getpathsofalldirectoriesabove-cannot-be-evaluated-after ...

  7. ubuntu16虚拟机迁移/移动/复制后无法上网

    修改grub配置 如果没有网卡,需要配置 sudo vi /etc/default/grub 将 GRUB_CMDLINE_LINUX="" 修改为 GRUB_CMDLINE_LI ...

  8. legend3---Windows 7/8/10 系统下Laravel框架的开发环境安装及部署详解(Vagrant + Homestead)

    legend3---Windows 7/8/10 系统下Laravel框架的开发环境安装及部署详解(Vagrant + Homestead) 一.总结 一句话总结: 1.安装的话就是下载好git,va ...

  9. 异步分发任务celery

    Celery简介 Celery是一个功能完备即插即用的任务队列.它使得我们不需要考虑复杂的问题,使用非常简单. celery适用异步处理问题,当遇到发送邮件.或者文件上传, 图像处理等等一些比较耗时的 ...

  10. .Net 逆向 Reflector之reflexil使用

    网上下载了一款商用的教育培训类软件,是用.Net写的,标榜的是免费的,但是只能试用一个月,商家很精明,用此方法推广招揽客户,但是公司在这一块却没有预算购买,一开始就想着既然是商用软件,安全机制做的肯定 ...