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正则用法实例讲解
Jun 21 Python
python入门教程之识别验证码
Mar 04 Python
详解Tensorflow数据读取有三种方式(next_batch)
Feb 01 Python
对Python中列表和数组的赋值,浅拷贝和深拷贝的实例讲解
Jun 28 Python
对pandas中iloc,loc取数据差别及按条件取值的方法详解
Nov 06 Python
解决新版Pycharm中Matplotlib图像不在弹出独立的显示窗口问题
Jan 15 Python
python如何获取当前文件夹下所有文件名详解
Jan 25 Python
详解python 爬取12306验证码
May 10 Python
Python中函数的基本定义与调用及内置函数详解
May 13 Python
python读取tif图片时保留其16bit的编码格式实例
Jan 13 Python
pandas数据选取:df[] df.loc[] df.iloc[] df.ix[] df.at[] df.iat[]
Apr 24 Python
讲解Python实例练习逆序输出字符串
May 06 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 addslashes和mysql_real_escape_string
2010/01/24 PHP
PHP去掉从word直接粘贴过来的没有用格式的函数
2012/10/29 PHP
解析php中两种缩放图片的函数,为图片添加水印
2013/06/14 PHP
如何取得中文字符串中出现次数最多的子串
2013/08/08 PHP
destoon安全设置中需要设置可写权限的目录及文件
2014/06/21 PHP
jquery 指南/入门基础
2007/11/30 Javascript
jquery tools之tabs 选项卡/页签
2009/07/25 Javascript
javascript 静态对象和构造函数的使用和公私问题
2010/03/02 Javascript
前端开发必须知道的JS之原型和继承
2010/07/06 Javascript
jQuery学习笔记[1] jQuery中的DOM操作
2010/12/03 Javascript
对Jquery中的ajax再封装,简化操作示例
2014/02/12 Javascript
js继承call()和apply()方法总结
2014/12/08 Javascript
JavaScript中的lastIndexOf()方法使用详解
2015/06/06 Javascript
分享一些常用的jQuery动画事件和动画函数
2015/11/27 Javascript
使用Angular.js开发的注意事项
2016/10/19 Javascript
JavaScript实现图片切换效果
2017/08/12 Javascript
深入理解Vue2.x的虚拟DOM diff原理
2017/09/27 Javascript
基于Swiper实现移动端页面图片轮播效果
2017/12/28 Javascript
原生JS实现的跳一跳小游戏完整实例
2019/01/27 Javascript
vue配置nprogress实现页面顶部进度条
2019/09/21 Javascript
jquery实现弹窗(系统提示框)效果
2019/12/10 jQuery
webstorm建立vue-cli脚手架的傻瓜式教程
2020/09/22 Javascript
Vue包大小优化的实现(从1.72M到94K)
2021/02/18 Vue.js
安装Python的web.py框架并从hello world开始编程
2015/04/25 Python
Python调用adb命令实现对多台设备同时进行reboot的方法
2018/10/15 Python
python的faker库用法
2019/11/28 Python
离线状态下在jupyter notebook中使用plotly实例
2020/04/24 Python
使用SimpleITK读取和保存NIfTI/DICOM文件实例
2020/07/01 Python
Pycharm 跳转回之前所在页面的操作
2021/02/05 Python
Marmot土拨鼠官网:美国专业户外运动品牌
2018/01/11 全球购物
大学班长的职责
2014/01/27 职场文书
运动会通讯稿50字
2014/01/30 职场文书
学生自我评价范文
2014/02/02 职场文书
《蚂蚁和蝈蝈》教学反思
2014/02/24 职场文书
观后感的写法
2015/06/19 职场文书
Linux中文件的基本属性介绍
2022/06/01 Servers