Python3.8官网文档之类的基础语法阅读


Posted in Python onSeptember 04, 2021

官网类的基础语法阅读

英文官方文档: https://docs.python.org/3.8/tutorial/classes.html

中文官方文档: https://docs.python.org/zh-cn/3.8/tutorial/classes.html

类提供了一种组合数据和功能的方法。

创建一个新类意味着创建一个新的对象类型,从而允许创建一个该类型的新实例。

1、类定义

最简单的类定义看起来像这样:

class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>

类定义与函数定义 (def 语句) 一样必须被执行才会起作用。

当进入类定义时,将创建一个新的命名空间,并将其用作局部作用域。因此,所有对局部变量的赋值都是在这个新命名空间之内。 特别的,函数定义会绑定到这里的新函数名称。

2、类对象

类对象支持两种操作:属性引用和实例化。

(1)属性引用

属性引用的标准语法: obj.name

有效的属性名称是,类对象被创建时,存在于类命名空间中的所有名称。 因此,如果类定义是这样的:

class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

那么 MyClass.iMyClass.f 就是有效的属性引用,将分别返回一个整数和一个函数对象。

类属性也可以被赋值,因此可以通过赋值来更改 MyClass.i 的值。

__doc__也是一个有效的属性,将返回所属类的文档字符串: "A simple example class"。

(2)实例化

类的实例化使用函数表示法。

可以把类对象视为是返回该类的一个新实例的不带参数的函数。 举例来说(假设使用上述的类):

x = MyClass()

创建类的新实例并将此对象分配给局部变量 x。

实例化操作(“调用”类对象)会创建一个空对象,也可以使用__init__() 创建带有特定初始状态的自定义实例。例如:

def __init__(self):
    self.data = []

此时,类的实例化操作会自动为新创建的类实例调用 __init__()。 因此在这个示例中,可以通过 x = MyClass() 语句获得一个经初始化的新实例:

__init__() 方法还可以有额外参数以实现更高灵活性。在这种情况下,提供给类实例化运算符的参数将被传递给 __init__()。 例如,:

>>> class Complex:
...     def __init__(self, realpart, imagpart):
...         self.r = realpart
...         self.i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)

3、实例对象

实例对象唯一操作是属性引用。 有两种有效的属性名称:数据属性和方法。

(1)数据属性

数据属性不需要声明,像局部变量一样,它们将在第一次被赋值时产生。

例如,如果 x 是上面创建的 MyClass 的实例,则以下代码段将打印数值 16,且不保留任何追踪信息:

x.counter = 1
while x.counter < 10:
    x.counter = x.counter * 2
print(x.counter)
del x.counter

(2)方法

方法是“从属于”对象的函数。 【注:方法是针对对象来说的,函数是针对类来说的】

(在 Python 中,方法这个术语并不是类实例所特有的:其他对象也可以有方法。例如,列表对象具有 append, insert, remove, sort 等方法。然而,在以下讨论中,我们使用方法一词将专指类实例对象的方法,除非另外显式地说明。)

实例对象的有效方法名称依赖于其所属的类。 【注:这里说的是方法名称】

根据定义,一个类中所有是函数对象的属性都是定义了其实例的相应方法。

因此在我们的示例中,x.f 是有效的方法引用,因为 MyClass.f 是一个函数,而 x.i 不是方法,因为 MyClass.i 不是一个函数。 但是x.f 与 MyClass.f 并不是一回事,它是一个方法对象,不是函数对象。

4、方法对象

通常,方法在绑定后立即被调用,在 MyClass 示例中,这将返回字符串 'hello world'。

x.f()

但是,立即调用一个方法并不是必须的: x.f 是一个方法对象,它可以被保存起来以后再调用。 例如:

xf = x.f
while True:
    print(xf())

将继续打印 hello world,直到结束。

虽然 f() 的函数定义指定了一个参数,但在上面调用 x.f() 时并没有带参数。 当不带参数地调用一个需要参数的函数时 Python 肯定会引发异常,即使参数实际未被使用。

方法的特殊之处就在于实例对象会作为函数的第一个参数被传入。 在我们的示例中,调用 x.f() 其实就相当于 MyClass.f(x)。 【注:也就是方法参数列表中的self】

总之,调用一个具有 n 个参数的方法就相当于调用再多一个参数的对应函数,这个参数值为方法所属实例对象,位置在其他参数之前。

当一个实例的非数据属性【注:即方法】被引用时,将搜索实例所属的类。

如果被引用的属性名称表示一个有效的类属性中的函数对象,会通过打包(指向)查找到的实例对象和函数对象 到一个抽象对象的方式来创建方法对象:这个抽象对象就是方法对象。 【注:xf = x.f,x.f 是一个方法对象】

当附带参数列表调用方法对象时,将基于实例对象和参数列表构建一个新的参数列表【注:self和参数列表】,并使用这个新参数列表调用相应的函数对象。

5、类和实例变量

一般来说,实例变量用于每个实例的唯一数据,而类变量用于类的所有实例共享的属性和方法:

【注:下例中kind是类变量,name是实例变量】

class Dog:

    kind = 'canine'         # class variable shared by all instances

    def __init__(self, name):
        self.name = name    # instance variable unique to each instance

>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.kind                  # shared by all dogs
'canine'
>>> e.kind                  # shared by all dogs
'canine'
>>> d.name                  # unique to d
'Fido'
>>> e.name                  # unique to e
'Buddy'

正如 名称和对象 中已讨论过的,共享数据可能在涉及可变对象的时候,例如列表和字典,导致令人惊讶的结果。

例如以下代码中的 tricks 列表不应该被用作类变量,因为所有的 Dog 实例将只共享一个单独的列表:

【注:类变量是所有实例所共享的,以下代码中的 tricks 列表不应该被用作类变量,实例调用 add_trick 时,就改变了 tricks 列表】

class Dog:

    tricks = []             # mistaken use of a class variable

    def __init__(self, name):
        self.name = name

    def add_trick(self, trick):
        self.tricks.append(trick)

>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.add_trick('roll over')
>>> e.add_trick('play dead')
>>> d.tricks                # unexpectedly shared by all dogs
['roll over', 'play dead']

正确的类设计应该使用实例变量:

class Dog:

    def __init__(self, name):
        self.name = name
        self.tricks = []    # creates a new empty list for each dog

    def add_trick(self, trick):
        self.tricks.append(trick)

>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.add_trick('roll over')
>>> e.add_trick('play dead')
>>> d.tricks
['roll over']
>>> e.tricks
['play dead']

6、补充说明

如果同样的属性名称同时出现在实例和类中,则属性查找会优先选择实例:

>>>
>>> class Warehouse:
        purpose = 'storage'
        region = 'west'

>>> w1 = Warehouse()
>>> print(w1.purpose, w1.region)
storage west
>>> w2 = Warehouse()
>>> w2.region = 'east'
>>> print(w2.purpose, w2.region)
storage east

方法的第一个参数常常被命名为 self。 这也不过就是一个约定: self 这一名称在 Python 中绝对没有特殊含义。但是要注意,不遵循此约定会使得你的代码对其他 Python 程序员来说缺乏可读性,而且也可以想像一个 类浏览器 程序的编写可能会依赖于这样的约定。

任何一个作为类属性的函数都为该类的实例定义了一个相应方法。 函数定义的文本并非必须包含于类定义之内:将一个函数对象赋值给一个局部变量也是可以的。 例如:

# Function defined outside the class
def f1(self, x, y):
    return min(x, x+y)

class C:
    f = f1

    def g(self):
        return 'hello world'

    h = g

现在 f, g 和 h 都是 C 类的引用函数对象的属性,因而它们就都是 C 的实例的方法,其中 h 完全等同于 g。 但请注意,本示例的做法通常只会令程序的阅读者感到迷惑。

方法可以通过使用 self 参数的方法属性调用其他方法:

class Bag:
    def __init__(self):
        self.data = []

    def add(self, x):
        self.data.append(x)

    def addtwice(self, x):
        self.add(x)
        self.add(x)

方法可以通过与普通函数相同的方式引用全局名称。与方法相关联的全局作用域就是包含其定义的模块。(类永远不会被作为全局作用域。)

虽然我们很少会有充分的理由在方法中使用全局作用域,但全局作用域存在许多合法的使用场景:举个例子,导入到全局作用域的函数和模块可以被方法所使用,在其中定义的函数和类也一样。

通常,包含该方法的类本身是在全局作用域中定义的,而在下一节中我们将会发现为何方法需要引用其所属类的很好的理由。

每个值都是一个对象,因此具有 类(也称为 类型),并存储为 object.__class__

到此这篇关于Python3.8官网文档之类的基础语法阅读的文章就介绍到这了,更多相关python3.8基础语法内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
详解Python中DOM方法的动态性
Apr 11 Python
Python对文件操作知识汇总
May 15 Python
python 转换 Javascript %u 字符串为python unicode的代码
Sep 06 Python
深入理解Python对Json的解析
Feb 14 Python
Python中的__slots__示例详解
Jul 06 Python
SVM基本概念及Python实现代码
Dec 27 Python
pip matplotlib报错equired packages can not be built解决
Jan 06 Python
Python处理菜单消息操作示例【基于win32ui模块】
May 09 Python
对Python中实现两个数的值交换的集中方法详解
Jan 11 Python
Python 调用 Windows API COM 新法
Aug 22 Python
python中struct模块之字节型数据的处理方法
Aug 27 Python
Python打开文件、文件读写操作、with方式、文件常用函数实例分析
Jan 07 Python
python实现Nao机器人的单目测距
Sep 04 #Python
python读取mnist数据集方法案例详解
Sep 04 #Python
Pyqt5将多个类组合在一个界面显示的完整示例
Sep 04 #Python
一小时学会TensorFlow2之基本操作2实例代码
Python torch.flatten()函数案例详解
Aug 30 #Python
Python之基础函数案例详解
Aug 30 #Python
python中使用 unittest.TestCase单元测试的用例详解
Aug 30 #Python
You might like
PHP对象相互引用的内存溢出实例分析
2014/08/28 PHP
PHP截取指定图片大小的方法
2014/12/10 PHP
PHP 验证登陆类分享
2015/03/13 PHP
PHP中数据类型转换的三种方式
2015/04/02 PHP
PHP采用超长(超大)数字运算防止数字以科学计数法显示的方法
2016/04/01 PHP
PHP实现的获取文件mimes类型工具类示例
2018/04/08 PHP
基于PHP实现短信验证码发送次数限制
2020/07/11 PHP
extjs form textfield的隐藏方法
2008/12/29 Javascript
使用javascript获取flash加载的百分比的实现代码
2011/05/25 Javascript
jquery及原生js获取select下拉框选中的值示例
2013/10/25 Javascript
javascript 弹出的窗口返回值给父窗口具体实现
2013/11/23 Javascript
通过XMLHttpRequest和jQuery实现ajax的几种方式
2015/08/28 Javascript
JavaScript判断DIV内容是否为空的方法
2016/01/29 Javascript
jQuery实现的tab标签切换效果示例
2016/09/05 Javascript
实例详解JSON取值(key是中文或者数字)方式
2017/08/24 Javascript
一文搞懂ES6中的Map和Set
2019/05/20 Javascript
JS实现分页导航效果
2020/02/19 Javascript
跟老齐学Python之变量和参数
2014/10/10 Python
python简单实现基于SSL的IRC bot实例
2015/06/15 Python
Python之Scrapy爬虫框架安装及使用详解
2017/11/16 Python
python3.4实现邮件发送功能
2018/05/28 Python
对python requests的content和text方法的区别详解
2018/10/11 Python
pytorch sampler对数据进行采样的实现
2019/12/31 Python
Pytorch转keras的有效方法,以FlowNet为例讲解
2020/05/26 Python
django models里数据表插入数据id自增操作
2020/07/15 Python
Ubuntu 20.04安装Pycharm2020.2及锁定到任务栏的问题(小白级操作)
2020/10/29 Python
Pat McGrath Labs官网:世界上最有影响力的化妆师推出的彩妆品牌
2018/01/07 全球购物
通信工程毕业生自荐信
2013/11/01 职场文书
后勤岗位职责
2013/11/26 职场文书
太太口服液广告词
2014/03/20 职场文书
党员干部观看《周恩来四个昼夜》思想汇报
2014/09/10 职场文书
群众路线教师自我剖析材料
2014/09/29 职场文书
2016年幼儿园万圣节活动总结
2016/04/05 职场文书
python中sys模块的介绍与实例
2021/04/17 Python
Kubernetes关键组件与结构组成介绍
2022/03/31 Servers
Python采集股票数据并制作可视化柱状图
2022/04/04 Python