c

codeye

V1

2022/10/14阅读:35主题:默认主题

犯罪现场

以简单的方式解释Python类 利用实例了解类的基本原理

当我第一次学习Python类的时候,我发现它真的很复杂,我没有掌握为什么需要了解它们的原因。在大学的一节课上,教授开始直接解释建立类的语法,而没有解释做这个特定主题的真正意义,并使用了非常无聊的例子,使我迷失了方向。

在这篇文章中,我想用一种不同的方式来解释Python类。我将开始解释为什么需要知道这些类,并展示一些已经建成的类的许多案例。一旦外部环境清楚了,下一步就是用一些例子和插图一步一步地展示如何定义类。

目录

类的介绍

创建一个类

构造函数方法

魔法

实例方法

  1. 类的介绍 当你开始学习Python时,你肯定遇到过这样一句话。

Python是一种面向对象的编程语言

这意味着用Python编程会导致到处被对象包围。在

我们给一个变量赋值,就是在创建一个对象。这个对象属于一个已经预先建立的特定类别,像数字、字符串、列表、字典等等。根据不同的类,该对象将有不同的属性和方法。

让我们看看一些对象和类的经典例子。

a = 28
print(type(a))
#<class 'int'>

我们定义了一个对象a,它属于Integer类。

ls = [1,2,3]
print(type(ls))
#<class 'list'>

这一次,新的对象属于List类。从这个对象中,我们可以调用已经在 Python 中预先建立的方法。为了看到对象中允许的所有方法,我们使用 dir 函数。

dir(l)

从输出结果中,我们可以注意到这个类可以提供三种类型的方法。

初始化方法__init__,以这种方式调用是因为它是初始化对象属性的方法。此外,一旦对象被创建,它就会被自动调用。

魔法

是两边有双下划线的特殊方法。例如,__add____mul__分别用来对同一类别的对象进行求和和乘法,而__repr__则返回对象的一个字符串表示。

实例方法是属于创建的对象的方法。例如,

ls.append(4)

在列表的末尾添加一个元素。

  1. 创建一个类

现在,我们将创建一个空的类,我们将在教程中逐步添加部分代码。

class Dog:
   pass

我们创建了一个名字为Dog的类,其中pass用来表示没有定义任何东西。

jack = Dog()
print(type(jack))
#<类 '__main__.Dog'> >

一旦我们定义了Dog类,我们就可以创建一个该类的对象,它被分配给变量jack。它是用我们用来调用一个函数的类似符号建立的。Dog()

这个对象也可以被称为实例。如果你发现某个地方写着 "instance "或 "object",不要感到困惑,它们总是指同一事物。

像以前一样,我们检查对象的类型。输出结果清楚地指出,该对象属于狗类。

  1. 初始化方法

除了前面显示的代码外,初始化方法__init__被用来初始化Dog类的属性。


class Dog:
  def __init__(self,name,breed,age):
    self.Name = name
    self.Breed = breed
    self.Age = age
    print("Name: {}, Breed: {}, Age: {}".format(self.Name,
                                             self.Breed,self.Age))

我们可以观察到,该方法有不同的参数。

self是作为第一个参数使用的标准符号,指的是对象,稍后将被创建。它对于访问属于该类的属性也很有用。

namebreedage是其余的参数。每个参数都是用来存储对象的特定属性值的。

名称、品种和年龄是定义的属性。注意这些属性通常不大写。在这篇文章中,它们是大写的,以突出属性和它们相应的值之间的区别。

jack = Dog('Jack','Husky',5)
#名字: Jack, 品种: Husky, 年龄: 5
print(jack)
#<__main__.Dog对象在0x000002551DCEFFD0>处
print(jack.Age)
#5

我们再次创建了这个对象,但是我们也指定了与属性相对应的值。如果你尝试运行这段代码,你会自动获得灰色窗口第二行中显示的文本。这是一个检查所定义的类是否运行良好的好方法。

同样值得注意的是,初始化方法在创建对象后被自动调用。这方面可以通过打印属性 "Age "的值来证明。你可以对其余的属性做同样的事情。

  1. 神奇的方法

也有可能以一种更复杂的方式来打印相同的信息。为了这个目的,我们使用神奇的方法__repr__

class Dog:
    def __init__(self,name,breed,age):
        self.Name = name
        self.Breed = breed
        self.Age = age
    def __repr__(self):
        return "Name: {}, Breed: {}, Age: {}".format(self.Name,
                                           self.Breed,self.Age)

方法 __repr__ 需要一个唯一的参数 selffrom,它可以访问对象的属性。

jack = Dog('Jack','Husky',5)
print(jack)
#Name: Jack, Breed: Husky, Age: 5
#名字。Jack, 品种: Husky, 年龄: 5

如果我们显示创建的新实例,我们可以查看属性和它们各自的值。

  1. 实例方法

睡觉还是醒着?

实例方法是属于类的方法。作为神奇的方法,它们接受一个输入参数self来访问类的属性。让我们看一个例子。

class Dog:
    def __init__(self,name,breed,age,tired):
        self.Name = name
        self.Breed = breed
        self.Age = age
        self.Tired = tired
    def __repr__(self):
        return "Name: {}, Breed: {}, Age: {}".format(self.Name,
                                           self.Breed,self.Age) 
    def Sleep(self):
        if self.Tired==True:
            return 'I will sleep'
        else:
            return "I don't want to sleep"

在初始化方法中,我们添加了一个新的参数tired,因此也添加了一个新的属性Tired。之后,我们定义了一个名为Sleep的新方法:如果该属性的值等于True,狗就会睡觉,否则就不会。

jack = Dog('Jack','Husky',5,tired=False)
print(jack.Sleep())

#我不想睡觉 这只狗不累,所以它不会睡觉。

最后的想法。

在这篇文章中,我对Python类进行了快速总结。我希望你能发现它对巩固你关于类的基础很有用。我没有解释其他类型的方法,静态方法和类方法,因为我想专注于最常见的方法。此外,另一个有趣的话题是类的继承性。

#2 实用的 Python类与实例变量

如何定义它们并与之互动

类是Python中最基本的一块,因为它是面向对象编程的本质。

Python中的所有东西都是一个对象,如整数、列表、字典、函数等等。每个对象都有一个类型,对象类型是用类来创建的。

实例是属于一个类的对象。例如,列表是 Python 中的一个类。当我们创建一个列表时,我们有一个列表类的实例。

在这篇文章中,我将集中讨论类和实例变量。我假设你对 Python 中的类有基本了解。如果没有,你仍然可以理解什么是类和实例变量,但其语法可能看起来有点让人不知所措。

如果你想了解基础知识,我也写过一篇关于Python类的介绍性文章。

我们先来看看类和实例变量。

类变量是在类内声明的,但在任何函数之外。实例变量是在构造函数中声明的,也就是__init__method。

考虑一下下面的类定义。

class Book():
   fontsize = 9
   page_width = 15
   def __init__(self, name, writer, length):
      self.name = name
      self.writer = writer
      self.length = length

假设图书类是由一个出版公司使用的。字体大小和页宽是类的变量。创建的每一个图书实例的字体大小为9,页宽为15厘米。

namewriter和length变量是在__init__方法中声明的,所以它们是实例变量。这些变量的值是在创建一个实例时确定的。

这是有道理的,因为字体大小和页面宽度通常是标准的。然而,名字、作者和长度是针对每本书(即实例)的。

将字体大小和页宽作为类变量来声明,可以节省我们很多时间和精力。假设出版公司决定改变书中使用的字体大小。如果它是一个实例变量,我们将需要为每个实例(即书)改变它。然而,由于它是一个类变量,一次赋值就可以完成每本书的工作。

让我们创建一个书类的实例。

book1 = Book("Intro to Python""John Doe", 50000)
print(book1.writer)
"John Doe"
print(book1.page_width)
15

尽管我们没有明确地将page_width变量分配给我们的实例,但它默认有这个属性。

我们可以为任何实例改变类变量的值(即覆盖它们)。假设我们想让book1更宽一点,所以我们将改变这个实例的page_width

book1.page_width = 17
print(book1.page_width)
17
print(Book.page_width)
15

正如你所看到的,我们只改变了book1实例的值。类变量的值保持不变。

我们定义的方法可以访问类的变量,但是我们需要小心。我将在下面的例子中告诉你原因。

我们为Book类定义一个方法,根据长度(字数)、字体大小和页宽来计算页数。

def number_of_pages(self): pages = (self.length * fontsize) / (page_width * 100) 返回页数

这个方法会引发一个NameError,说'fontsize'没有被定义。page_width "也是如此。虽然这些是类变量,但我们需要告诉方法从哪里获得它们。

我们可以从实例本身或从类中获取它们。

#使用实例

def number_of_pages(self):
   pages = (self.length * fontsize) / (page_width * 100)
   return pages

#使用该类

def number_of_pages(self):
   pages = (self.length * self.fontsize) / (self.page_width * 100)
   return pages

这两种方法都可以工作。让我们来做一个例子。

book1 = Book("Intro to Python", "John Doe", 50000) book1_pages = book1.number_of_pages() print(book1_pages) 300 更新类的变量将影响该类的所有实例。这是一个很好的功能,可以为我们节省时间和精力。然而,我们也需要注意变化的程度。

下面是一个例子。

book1 = Book("Intro to Python""John Doe", 50000)
book2 = Book("Pandas介绍""Jane Doe", 40000)
print(book1.fontsize, book2.fontsize)
(9, 9)
book.fontsize = 11
print(book1.fontsize, book2.fontsize)
(11, 11)

实例通过它们所属的类访问类的变量。让我们做一个例子来说明我的意思。

__dict__方法可以用来查看一个实例或类的属性。

book1 = Book("Intro to Python""John Doe", 50000)
print(book1.__dict__)
{'name''Intro to Python''writer''John Doe''length': 50000}
print(book1.fontsize)
9

当我们打印出book1的数据属性时,我们没有看到字体大小和页宽。然而,我们可以通过打印出来看到book1有fontsize属性。

实例(book1)通过类访问了类的变量。让我们也在Book类上应用__dict__方法。 实例(book1)通过类访问了类的变量。让我们也在Book类上应用__dict__方法。

print(Book.__dict__)
'__module__''__main__''fontsize': 9, 
'page_width': 15, 
'__init__': <function Book.__init__ at 0x7f6cc5f54620>, 
'number_of_pages': <function Book.number_of_pages at 0x7f6cc5f548c8>, 
'__dict__': <attribute '__dict__' of 'Book' objects>, 
'__weakref__': <attribute '__weakref__' of 'Book' objects>, '__doc__': None}

类的变量以及方法和其他一些东西被打印出来。

结论 类变量会影响整个类。因此,当一个类变量被更新时,所有的实例都被更新。这很方便,但我们也需要小心。如果不小心使用,可能会发生不希望发生的后果。

实例变量对每个实例都有唯一的值。我们在创建实例时为它们赋值。

所有的实例在一开始都采取相同的类变量值,但我们可以在以后为一个实例更新它们。我们对一个实例所做的改变不会影响其他实例的类变量值。

#3 一个犯罪现场被发现,在证据中,有一份代理人的名单,没有明显的联系。

你在记录部门的工作是将这份名单与警方的记录进行比对,找到一个完全匹配的名单。

你的函数将收到一个列表作为第一个参数,即被盗记录,然后是一个列表,即数据库。

只有在包含相同顺序的相同名字的情况下才会找到匹配,不多不少。如果第一个参数是一个空列表,你的代码应该返回 None。

数据库将总是包含不止一个列表。匹配应该返回 "找到匹配"。如果没有找到匹配,你的代码应该返回 "没有匹配"。

例子:

agents(["John""Sarah"], 
[["John""Sarah"], ["Mary""David"]) 
== "找到匹配的"

你作为警局的首席技术骨干,任务是建立辖区内的住户画像,包括姓名、性别、年龄、身高体重等自然人属性;

同时,也要留出扩展的灵活性。添加、籍贯、国籍、工作、信仰等社会属性;

结合下面两篇文章学习SQL,我们思考如何建立数据库并且设计编码为何用到面向对象的编程OOP方法比如:class

满足既可以通过姓名,查询姓名为关键词; 也可以通过年龄段、身高等等数值范围查询结果满足所有符合的人群;

分类:

后端

标签:

后端

作者介绍

c
codeye
V1