Python学习(九)类(一)

​ 面向对象编程是最有效的软件编写方法之一。在面向对象编程中,编写表示现实世界中的事物和情景的类。并基于这些类来创建对象。编写类时,定义一大类对象都有的通用行为。基于类创建对象时,每个对象都自动具备这种通用行为,然后可根据需要赋予每个对象独特的个性。使用面向对象编程可模拟现实情景。

​ 根据类来创建对象被称为实例化。这让你能使用类的实例。你将指定可在实例中存储什么信息,定义可对这些实例执行哪些操作。你还将编写一些类来扩展既有类的功能,让相似的类能够高效的共享代码。你将自己编写的类存储在模块中,并在自己的程序文件中导入其他程序员编写的类。

​ 理解面向对象编程有助于你像程序员那样看世界,还可以帮助你真正明白自己编写的代码。不仅是各行代码的作用,还有代码背后更宏大的概念。了解类背后的概念可培养逻辑思维,让你能够通过编写程序来解决遇到的几乎任何问题。

1.1 创建和使用类

​ 使用类几乎可以模拟任何东西。下面编写一个表示小狗的简单Dog类。它表示的不是特定的小狗,而是任何的小狗。对于大多数宠物狗,我们都知道什么呢?宠物狗的名字和年龄。同时我们还知道,大多数的小狗都会蹲下和打滚。我们的Dog类将包含它们。

1.1.1 创建Dog类

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

class Dog():"""一次模拟小狗的简单尝试"""def __init__(self, name, age):
        """初始化属性name和age"""
④        self.age = age
        self.name = name
        
⑤    def sit(self):
        """模拟小狗被命令时蹲下"""
        print self.name.title() + " is sitting."
        
    def roll(self):
        """模拟小狗被命令时打滚"""
        print self.name.title() + " rolled over!"

​ 这里需要注意的地方很多,但不必担心。在本章中充斥着这样的结构,你有大把的机会熟悉它。在①处,定义了一个名为Dog的类。根据约定,在Python中,首字母大写的名称指的是类。这个类定义中的括号是空的,因为我们要从空白创建这个类。在②处,我们编写了一个文档字符串,对这个类的功能作了描述。

1.方法_init_()

​ 类中的函数被称为方法。在前面学到的有关函数的一切都适用于方法,就目前而言,唯一重要的差别是调用方法的方式。③处_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。以self为前缀的变量都可供类中的所有方法使用,我们还可以通过类的任何实例来访问这些变量。self.name = name获取存储在形参name中的值,并将其存储到变量name中,然后该变量被关联到当前创建的实例。self.age = age在作用与此类似。像这样可通过实例访问的变量称为属性

​ ⑤处Dog类还定义了另外两个方法:sit()和roll()。由于这两个方法不需要额外的信息,如名字或年龄,因此它们只有一个形参self。

1.2 根据类创建实例

​ 可将类视为有关如何创建实例的说明。Dog类是一系列的说明,让Python知道如何创建表示特定小狗的实例。

​ 下面创建一个表示特定小狗的实例:

class Dog():
    """一次模拟小狗的简单尝试"""

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

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

    def roll(self):
        """模拟小狗被命令时打滚"""
        print self.name.title() + " rolled over!"


① my_dog = Dog('kitty', 3)print 'My dog name is ' + my_dog.name.title() + ' .'print 'My dog age is ' + str(my_dog.age) + 'years old.'

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

1.访问属性

​ 要访问实例的属性,可使用句点表示法。在②处,我们编写了如下的代码来访问my_dog的属性name的值。

my_dog.name

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

​ 看一下上述代码的输出:

My dog name is Kitty .
My dog age is 3years old.
2.调用方法

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

my_dog.sit()
my_dog.roll()

​ 要调用方法,可指定实例的名称(这里是my_dog)和要调用的方法,并用句点分隔它们。遇到代码my_dog.sit()时,Python在类Dog中查找方法sit()并运行其代码。Python会以同样的方式解读代码my_dog.roll()。

​ 可以看到它按照我们的命令做了:

Kitty is sitting.
Kitty rolled over!

这种语法很有用。如果给属性和方法指定了合适的描述性名称,如name,age,sit()和roll(),即便是从未见过代码,我们也能轻松的推断出他是干什么的。

2.使用类和实例

​ 你可以使用类来模拟现实世界中的很多情景。类编写好之后,你的大部分时间都将花在使用根据类创建的实例上。你需要执行的一个重要任务是修改实例的属性,你可以直接修改实例的属性,也可以编写方法以特定的方式进行修改。

2.1 Car类

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

class Car():
    """模拟汽车的简单尝试"""def __init__(self, make, model, year):
        """初始化描述汽车的属性"""
        self.make = make
        self.model = model
        self.year = year

②    def get_descriptive_name(self):
        """返回描述信息"""
        long_name = str(self.year) + " " + self.make + " " + self.model
        return long_name


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

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

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

2020 audi a4

​ 为了让这个类更有趣,下面给它添加一个随时间变化的属性,它存储汽车的总里程。

2.2 给属性指定默认值

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

​ 下面添加一个名为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

②    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()

​ 现在,当Python调用方法_init_()来创建新实例时,将像前一个示例以属性的方式存储制造商等。接下来,Python将创建一个名为odometer_reading的属性,①处将其初始值设置为0。在②处,我们还定义一个名为read_odometer的方法,它让你能够轻松的获取汽车的里程数。

​ 在一开始的时候,汽车的里程数为0。

2020 audi a4
This car has 0 miles on it.

​ 但是在真正出售汽车时,为0里程的并不多,因此我们需要一个修改该属性的值的途径。

2.3 修改属性的值

​ 可以以三种不同的方式修改属性的值,①直接通过实例进行修改,②通过方法进行设置,③通过方法进行递增(增加特定的值)。下面依次介绍这些方法。

1.直接修改属性的值

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

① my_new_car.odometer_reading = 100
my_new_car.read_odometer()

​ 在①处,我们使用句点表示法来直接访问并设置汽车的属性odometer_reading。这行代码让Python在实例my_new_car中找到属性odometer_reading,并将该属性的值设置为100。

2020 audi a4
This car has 100 miles on it.

​ 有时候需要像这样直接访问属性,但其他时候需要编写对属性进行更新的方法。

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

    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.odometer_reading = 100
② my_new_car.update_odometer(100)
my_new_car.read_odometer()

​ 对Car类所做的唯一修改是在①处添加了方法update_odometer()。这个方法接收一个里程值,并将其存储到self.odometer_reading中。在②处,我们调用了update_odometer(),并向它传递了实参100(该实参对应方法定义中的形参mileage)。它将里程表的读数设置为100。

2020 audi a4
This car has 100 miles on it.

​ 接着对方法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

    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 can't roll back an odometer!"

my_new_car = Car("audi", "a4", 2020)
print my_new_car.get_descriptive_name()
# my_new_car.odometer_reading = 100
my_new_car.update_odometer(100)
my_new_car.update_odometer(0)
my_new_car.read_odometer()

​ 现在,update_odometer()在修改属性前先检查指定的读数是否合理。如果新指定的里程大于或等于原来的里程,将里程改为新指定的里程。否则我们就发出警告,指出不可以将里程往回拨。

2020 audi a4
You can't roll back an odometer!
This car has 100 miles on it.
3. 通过方法对属性的值进行递增

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

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

    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 can't roll back an odometer!"def increment_odometer(self,miles):
        """将里程表增加指定的量"""
        self.odometer_reading+=miles

② my_old_car = Car("audi", "a4", 2020)
print my_old_car.get_descriptive_name()
③ my_old_car.update_odometer(100)
my_old_car.read_odometer()
④ my_old_car.increment_odometer(100)
my_old_car.read_odometer()

​ 在①处,新增的方法increment_odometer()接收一个单位为里的数字,并将其加入到self.odometer_reading中。在②处,我们创建了一辆二手车,my_old_car。在③处,我们调用方法update_odometer()并传入100,将这辆二手车的里程表的读数设置为100。在④处,我们调用increment_odometer()并传入100,以增加从购买到登记期间的100里。

2020 audi a4
This car has 100 miles on it.
This car has 200 miles on it.

​ 你可以轻松的修改这个方法,以禁止增量为负数,从而防止有人利用它来回拨里程表。


今天先写到这喽!下一篇开始从类的集成开始。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中的softmax多分是指使用softmax函数作为激活函数的多分模型。softmax回归是一种常用的多分算法,也称为多Logistic回归。它在NLP中与最大熵模型等价,并广泛用作深度学习模型的最后一层进行分预测。该模型假设是一个概率模型,通过将输入的实数向量转化为概率分布来进行分。 在Python中,我们可以使用各种深度学习框架来实现softmax多分,比如PyTorch。在PyTorch中,可以使用torch.max()函数来计算每行中的最大值,并返回最大值和对应的索引。这可以用来进行分预测,其中最大值对应于预测的别。 此外,在处理图像时,我们可以使用Python中的图像处理库,比如PIL(Python Imaging Library)。然而,由于PIL仅支持到Python 2.7,并且年久失修,因此一群志愿者创建了兼容Python 3的版本,名为Pillow。我们可以通过安装Pillow来使用PIL的功能。这对于图像预处理和数据增强非常有用。 综上所述,Python提供了丰富的工具和库来实现softmax多分,包括各种深度学习框架和图像处理库,使得我们可以轻松地构建和训练多分模型。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [[机器学习]Softmax回归解决多(3)分问题(梯度上升+随机梯度上升),含python代码实现,简单可视化](https://blog.csdn.net/weixin_44458659/article/details/109268544)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [《PyTorch深度学习实践》第讲 Softmax Classifier解决多分问题](https://blog.csdn.net/weixin_45626133/article/details/129986201)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值