文章目录

  • 类(Classes)
    • 名称和对象(A Word About Names and Objects)
    • python 作用域和命名空间
      • 作用域和命名空间示例
    • 初识类(A First Look at Classes)
      • 类定义语法(Class Definition Syntax)
      • 类对象(Class Objects)
      • 实例对象(Instance Objects)
      • 方法对象(Method Objects)
      • 类和实例变量
    • 继承
      • 多重继承
    • 私有变量(Private Variables)
    • 零碎的知识(Odds and Ends)
    • 迭代器(iterator)
    • 生成器(Generators)
    • 生成器表达式

参考:python 官方教学英文文档

类(Classes)

类提供了一种将数据和功能捆绑在一起的方法。创建新类会创建一个新类型的对象,允许创建该类型的新实例。每个类实例都可以附加属性来维护其状态。类实例还可以有(由类定义的)方法来修改其状态。

与其他编程语言相比,Python的类机制以最少的语法和语义添加类。它混合了c++和Modula-3中的类机制。Python类提供了面向对象编程的所有标准功能:类继承机制允许多个基类,派生类可以覆盖其基类或类的任何方法,方法可以调用基类的同名方法。对象可以包含任意数量和类型的数据。和模块一样,类也具有Python的动态特性:它们在运行时创建,创建后可以进一步修改。

在c++术语中,类成员(包括数据成员)通常是公有的(私有变量除外),所有成员函数都是虚的。与Modula-3一样,没有从方法中引用对象成员的简写方式:method函数显式地声明了表示对象的第一个参数,该参数由调用隐式地提供。在Smalltalk中,类本身就是对象。这为导入和重命名提供了语义。与c++和Modula-3不同,内置类型可以用作用户扩展的基类。此外,像在c++中一样,大多数具有特殊语法的内置操作符(算术操作符、下标等)可以为类实例重新定义。

名称和对象(A Word About Names and Objects)

对象具有个性,可以将多个名称(在多个作用域中)绑定到同一个对象。这在其他语言中称为别名。初看Python时,这通常不会被理解,在处理不可变的基本类型(数字、字符串、元组)时,可以安全地忽略它。然而,别名对于Python代码中涉及可变对象(如列表、字典和大多数其他类型)的语义可能有惊人的影响。这通常有利于程序,因为别名在某些方面的行为类似于指针。例如,传递对象是廉价的,因为实现只传递一个指针;如果函数修改了作为参数传递的对象,调用者将看到变化——这消除了Pascal中两种不同的参数传递机制的需要。

python 作用域和命名空间

在介绍类之前,我首先要告诉你一些Python的作用域规则。类定义使用了一些巧妙的命名空间技巧,您需要知道作用域和命名空间是如何工作的,才能完全理解发生了什么。顺便说一句,这方面的知识对任何高级Python程序员都很有用。

让我们从一些定义开始。

命名空间是名称到对象的映射。大多数命名空间目前都以Python字典的形式实现,但这通常不会引起任何注意(除了性能),将来可能会发生变化。

命名空间的例子包括:

  • 内置名称的集合(包含abs()等函数和内置异常名称);
  • 模块中的全局名称;
  • 以及函数调用中的局部名称。

在某种意义上,对象的属性集合也形成了一个命名空间。关于命名空间,重要的是要知道,不同命名空间中的名称之间绝对没有关系;例如,两个不同的模块可能都定义了函数maximize而不会混淆——模块的用户必须在前面加上模块名称。

顺便说一下,我使用单词attribute来表示句点后面的任何名称-例如,在表达式z.real中,real是对象z的一个属性。严格地说,在模块中对名称的引用是属性引用:modname.funcname, modname是一个模块对象,Funcname是它的一个属性。在这种情况下,模块属性和模块中定义的全局名称之间恰好有一个直接的映射:它们共享相同的命名空间。

属性可以是只读的,也可以是可写的。在后一种情况下,可以对属性赋值。模块属性是可写的:modname.the_answer = 42。可写属性也可以用del语句删除。例如,del modname.the_answerthe_answer将从modname命名的对象中移除。

名称空间在不同的时刻创建,具有不同的生命周期。包含内置名称的名称空间是在Python解释器启动时创建的,并且永远不会删除。模块的全局命名空间是在读入模块定义时创建的;通常,模块名称空间也会持续到解释器退出。解释器的顶层调用执行的语句(从脚本文件中读取或以交互方式读取)被认为是名为__main__的模块的一部分,因此它们有自己的全局名称空间。(内置名称实际上也存在于module中。)

函数的本地名称空间在调用函数时创建,在函数返回或引发函数内未处理的异常时删除。(实际上,用遗忘来描述实际发生的事情会更好。)当然,每个递归调用都有自己的本地名称空间。

作用域是Python程序的文本区域,在这里可以直接访问命名空间。这里的“直接可访问”意味着对名称的非限定引用试图在名称空间中查找该名称。

虽然作用域是静态确定的,但它们是动态使用的。在执行过程中的任何时候,都有3或4个嵌套的作用域,它们的命名空间可以直接访问:最内层作用域,首先被搜索,包含局部名称任何外层函数的作用域,从最近的外层作用域开始搜索,包含非局部名称,但也包含非全局名称。倒数第二个作用域包含当前模块的全局名称。然后,所有的引用和赋值都直接指向包含模块全局名称的中间作用域。要重新绑定在最内层作用域之外的变量,可以使用nonlocal语句;如果没有声明为非局部变量,这些变量是只读的(试图写入这样的变量只会在最内层的作用域中创建一个新的局部变量,而同名的外部变量保持不变)。

通常,局部作用域引用当前函数(按文本表示)的局部名称。在函数外部,局部作用域引用与全局作用域相同的命名空间:模块的命名空间。类定义在局部作用域中又放置了一个命名空间。

重要的是要意识到作用域是按文本确定的:在模块中定义的函数的全局作用域是该模块的命名空间,无论该函数是从哪里或以什么别名调用的。另一方面,名称的实际搜索是在运行时动态完成的——然而,语言定义正在朝着在“编译”时进行静态名称解析的方向发展,因此不要依赖动态名称解析!(事实上,局部变量已经是静态确定的。)

Python有一个特殊的特点——如果没有全局或非局部语句生效,那么对名称的赋值总是进入最内层的作用域。赋值并不复制数据——它们只是将名称绑定到对象上。删除也是如此:语句del x从局部作用域引用的命名空间中移除对x的绑定。事实上,所有引入新名称的操作都会使用局部作用域:特别是,import语句和函数定义会在局部作用域中绑定模块或函数的名称。

global语句可以用来指出某些变量位于全局作用域中,并且应该在全局作用域中反弹;nonlocal语句指出某些变量位于一个封闭作用域中,并且应该被反弹到该作用域中。

作用域和命名空间示例

这个例子演示了如何引用不同的作用域和名称空间,以及全局和非局部变量绑定如何影响变量绑定:

def scope_test():def do_local():spam = "local spam"def do_nonlocal():nonlocal spamspam = "nonlocal spam"def do_global():global spamspam = "global spam"spam = "test spam"do_local()print("After local assignment:", spam)do_nonlocal()print("After nonlocal assignment:", spam)do_global()print("After global assignment:", spam)scope_test()
print("In global scope:", spam)

示例代码的输出是:

After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam

注意local赋值(默认值)没有改变scope_test对spam的绑定。nonlocal赋值更改了scope_test对垃圾邮件的绑定,而global赋值更改了模块级绑定。

您还可以看到,在global赋值之前没有针对spam的绑定。

初识类(A First Look at Classes)

类引入了一些新的语法、三种新的对象类型和一些新的语义。

类定义语法(Class Definition Syntax)

类定义的最简单形式如下:

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

类定义和函数定义(def语句)一样,必须在它们起作用之前执行。(您可以将类定义放在if语句的分支中,或者放在函数中。)

在实践中,类定义中的语句通常是函数定义,但也允许使用其他语句,有时还很有用——我们稍后再讨论这个问题。类内部的函数定义通常有一种特殊形式的参数列表,这是由方法的调用约定规定的—同样,这将在后面解释。

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

当一个类定义被正常保留(通过结尾)时,一个类对象被创建。这基本上是类定义创建的命名空间内容的包装器;我们将在下一节中了解更多关于类对象的知识。原始的局部作用域(在输入类定义之前生效的作用域)被恢复,类对象在这里被绑定到类定义头文件中给出的类名(本例中的ClassName)

类对象(Class Objects)

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

属性引用使用Python中所有属性引用使用的标准语法:obj.name。有效的属性名称是创建类对象时类名称空间中的所有名称。所以,如果类定义是这样的:

class MyClass:"""A simple example class"""i = 12345def f(self):return 'hello world'

这时,MyClass.iMyClass.f 是有效的属性引用,分别返回一个整数和函数对象。类的属性也可以被赋值,比如可以给MyClass.i 指派一个值。

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

类实例化使用函数表示法。假设类对象是一个返回类的新实例的无参数函数。例如(假设上面的类):

x = MyClass()

创建类的新实例并将该对象赋值给局部变量x。

实例化操作(“调用”类对象)创建一个空对象。许多类喜欢创建具有自定义为特定初始状态的实例的对象。因此,类可以定义一个名为__init__()的特殊方法,如下所示:

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

当类定义了__init__()方法时,类实例化会自动为新创建的类实例调用__init__()。所以在这个例子中,一个新的初始化实例可以通过以下方式获得:

x = MyClass()

当然,__init__()方法可能有参数以获得更大的灵活性。在这种情况下,给类实例化操作符的参数被传递给__init__()。例如:

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

实例对象(Instance Objects)

现在我们能用实例对象做什么呢?实例对象所理解的惟一操作是属性引用。有两种有效的属性名称: 数据属性和方法。

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

另一种实例属性引用是方法。方法是“属于”对象的函数。(在Python中,术语方法并不是类实例所独有的:其他对象类型也可以有方法。例如,列表对象具有append、insert、remove、sort等方法。然而,在接下来的讨论中,除非另有明确说明,我们将只使用术语方法来表示类实例对象的方法。)

方法对象(Method Objects)

通常,一个方法会在它被绑定之后被调用:

x.f()

在MyClass示例中,这将返回字符串'hello world'。但是,没有必要立即调用一个方法:x.f是一个方法对象,可以存储起来,以后再调用。例如:

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

调用方法时到底发生了什么?您可能已经注意到,尽管f()的函数定义指定了一个参数,但在调用x.f()时没有使用上述参数。对于参数而言,发生了什么?当然,当调用一个需要实参的函数时,Python会抛出异常——即使实参实际上没有使用……

实际上,您可能已经猜到了答案:方法的特殊之处在于,实例对象作为函数的第一个参数传递。在我们的例子中,调用x.f()完全等同于MyClass.f(x)。通常,调用带有n个参数列表的方法相当于调用带有参数列表的对应函数,该参数列表是通过在第一个参数之前插入方法的实例对象创建的。

如果你仍然不明白方法是如何工作的,看一下实现可能会弄清楚。当引用实例的非数据属性时,将搜索实例的类。如果属性名是一个有效的类属性,而且是一个函数对象,那么方法对象就是把实例对象和函数对象(指向函数对象的指针)封装在一个抽象对象中,这个抽象对象就是方法对象。当使用参数列表调用method对象时,会根据实例对象和参数列表构建一个新的参数列表,然后使用这个新参数列表调用函数对象。

类和实例变量

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

class Dog:kind = 'canine'         # class variable shared by all instancesdef __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实例共享一个列表:

class Dog:tricks = []             # mistaken use of a class variabledef __init__(self, name):self.name = namedef 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 = nameself.tricks = []    # creates a new empty list for each dogdef 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']

数据属性可以由方法引用,也可以由对象的普通用户(“客户端”)引用。换句话说,类不能用于实现纯抽象数据类型。事实上,Python中没有任何东西可以强制数据隐藏——这都是基于约定的。(另一方面,用C编写的Python实现可以完全隐藏实现细节,并在必要时控制对对象的访问;这可以被用c编写的Python扩展使用)

注意,只要避免名称冲突,客户机可以向实例对象添加自己的数据属性,而不会影响方法的有效性——同样,命名约定可以在这里省去很多麻烦。

从方法内部引用数据属性(或其他方法!)没有捷径。我发现这实际上增加了方法的可读性:在浏览方法时,不会混淆局部变量和实例变量。

通常,方法的第一个参数称为self。这只不过是一种约定:名称self对Python绝对没有特殊意义。但是,请注意,如果不遵循这种约定,其他Python程序员可能很难读懂您的代码,而且可以想象,可能会编写依赖于这种约定的类浏览器程序。

任何作为类属性的函数对象都为该类的实例定义了一个方法。函数定义不必以文本形式包含在类定义中:将函数对象赋值给类中的局部变量也可以。例如:

# Function defined outside the class
def f1(self, x, y):return min(x, x+y)class C:f = f1def g(self):return 'hello world'h = g

现在f, gh都是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__

继承

当然,如果不支持继承,语言特性就配不上“类”这个名字。派生类定义的语法如下所示:

class DerivedClassName(BaseClassName):<statement-1>...<statement-N>

名称BaseClassName必须在包含派生类定义的作用域中定义。也允许使用其他任意表达式代替基类名。这可能很有用,例如,当基类在另一个模块中定义时:

class DerivedClassName(modname.BaseClassName):

派生类定义的执行过程与基类相同。在构造类对象时,会记住基类。这用于解析属性引用:如果在类中没有找到请求的属性,则继续在基类中查找。如果基类本身派生自其他类,则递归应用此规则。

派生类的实例化没有什么特别的:DerivedClassName()创建类的一个新实例。方法引用的解析方法如下:搜索相应的类属性,必要时向下查找基类链,如果生成函数对象,则方法引用是有效的。

派生类可以覆盖其基类的方法。因为方法在调用同一对象的其他方法时没有特殊权限,基类的方法在调用同一基类中定义的另一个方法时,最终可能会调用重写它的派生类的方法。(对于c++程序员:Python中的所有方法实际上都是virtual方法。)

派生类中的重写方法实际上可能希望扩展而不是简单地替换同名的基类方法。有一种直接调用基类方法的简单方法:只需调用BaseClassName.methodname(self, arguments)。这有时对客户也很有用。(注意,这只在基类在全局作用域中作为BaseClassName可访问时才有效。)

Python有两个处理继承的内置函数:

  • 使用isinstance()检查实例的类型: 只有当obj.__class__int 或者是从其他int类中派生得到时,isinstance(obj, int) 才为True
  • 使用issubclass()检查类继承: issubclass(bool, int)True,因为boolint的子类。然而,issubclass(float, int)False,因为float不是int的子类。

多重继承

Python还支持一种形式的多重继承。具有多个基类的类定义如下所示:

class DerivedClassName(Base1, Base2, Base3):<statement-1>...<statement-N>

对于大多数目的,在最简单的情况下,您可以认为从父类继承的属性的搜索是深度优先、从左到右的,而不是在层次结构中有重叠的同一个类中搜索两次。因此,如果在DerivedClassName中没有找到某个属性,则在Base1中搜索它,然后(递归地)在Base1的基类中搜索它,如果在Base1中没有找到它,则在Base2中搜索它,以此类推。

事实上,实际情况要比这稍微复杂一些;方法解析顺序动态更改,以支持对super()的协作调用。这种方法在其他一些多继承语言中称为调用-下一个方法,比单继承语言中的超级调用更强大。

动态排序是必要的,因为所有多重继承的情况都表现出一个或多个菱形关系(从最底层类可以通过多条路径访问至少一个父类)。例如,所有类都继承自object,所以任何多重继承的情况都提供了一条到达object的路径。为了防止基类被多次访问,动态算法以保留每个类中指定的从左到右的顺序的方式线性化搜索顺序,只调用每个父类一次,这是单调的(意味着一个类可以在不影响父类的优先级顺序的情况下子类化)。综上所述,这些属性使得设计可靠且可扩展的多继承类成为可能。

私有变量(Private Variables)

只有在对象内部才能访问的“私有”实例变量在Python中并不存在。然而,大多数Python代码都遵循一个约定: 带有下划线前缀的名称(例如_spam)应该被视为API的非公共部分(无论它是函数、方法还是数据成员)。它应该被视为一个实现细节,可以在不通知的情况下进行更改。

由于类私有成员有一个有效的用例(即避免名称与子类定义的名称冲突),因此对这种称为名称mangling的机制的支持是有限的。形式为__spam的任何标识符(至少两个前导下划线,最多一个尾随下划线)将被文本替换为_classname__spam,其中classname是去掉前导下划线的当前类名。只要发生在类的定义中,就不考虑标识符的语法位置。

名称篡改有助于让子类覆盖方法而不破坏类内方法调用。例如:

class Mapping:def __init__(self, iterable):self.items_list = []self.__update(iterable)def update(self, iterable):for item in iterable:self.items_list.append(item)__update = update   # private copy of original update() methodclass MappingSubclass(Mapping):def update(self, keys, values):# provides new signature for update()# but does not break __init__()for item in zip(keys, values):self.items_list.append(item)

即使MappingSubclass要引入__update标识符,上面的例子也可以工作,因为它分别被替换为Mapping类中的_Mapping__updateMappingSubclass类中的_MappingSubclass__update

请注意,mangling规则的设计主要是为了避免事故;仍然可以访问或修改被认为是私有的变量。这甚至在特殊情况下也很有用,比如在调试器中。

注意,传递给exec()eval()的代码不会将调用类的类名视为当前类;这与global语句的效果类似,global语句的效果同样局限于一起按字节编译的代码。同样的限制也适用于getattr()setattr()delattr(),以及直接引用__dict__时。

零碎的知识(Odds and Ends)

有时,有一个类似于Pascal“record”或C“struct”的数据类型是很有用的,它将一些命名的数据项捆绑在一起。空类定义会很好:

class Employee:passjohn = Employee()  # Create an empty employee record# Fill the fields of the record
john.name = 'John Doe'
john.dept = 'computer lab'
john.salary = 1000

一段需要特定抽象数据类型的Python代码通常可以被传递给一个模拟该数据类型的方法的类。例如,如果您有一个格式化文件对象中的某些数据的函数,那么您可以定义一个具有read()readline()方法的类,它们从字符串缓冲区获取数据,并将其作为参数传递。

实例方法对象也有属性:m.__self__是带有m()方法的实例对象,m.__func__是与方法相对应的函数对象。

迭代器(iterator)

到目前为止,你可能已经注意到大多数容器对象都可以使用for语句循环遍历:

for element in [1, 2, 3]:print(element)
for element in (1, 2, 3):print(element)
for key in {'one':1, 'two':2}:print(key)
for char in "123":print(char)
for line in open("myfile.txt"):print(line, end='')

这种访问方式清晰、简洁、方便。迭代器的使用非常普遍,并且使Python更加统一。在幕后,for语句调用容器对象上的iter()。该函数返回一个迭代器对象,该对象定义了方法__next__(),该方法每次访问容器中的一个元素。当没有更多的元素时,__next__()会引发StopIteration异常,告诉for循环终止。你可以使用next()内置函数调用__next__()方法;这个例子展示了它是如何工作的:

>>> s = 'abc'
>>> it = iter(s)
>>> it
<str_iterator object at 0x10c90e650>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):File "<stdin>", line 1, in <module>next(it)
StopIteration

在了解了迭代器协议背后的机制之后,将迭代器行为添加到类中就很容易了。定义一个__iter__()方法,它返回一个带有__next__()方法的对象。如果类定义了__next__(),那么__iter__()可以只返回self:

class Reverse:"""Iterator for looping over a sequence backwards."""def __init__(self, data):self.data = dataself.index = len(data)def __iter__(self):return selfdef __next__(self):if self.index == 0:raise StopIterationself.index = self.index - 1return self.data[self.index]
>>> rev = Reverse('spam')
>>> iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>> for charin rev:
...    print(char)
...
m
a
p
s

生成器(Generators)

生成器是创建迭代器的简单而强大的工具。它们被写得像普通函数一样,但在想要返回数据时使用yield语句。每次在它上调用next()时,生成器将从停止的地方恢复(它记住所有数据值和最后执行的语句)。一个例子表明,生成器可以很容易地创建:

def reverse(data):for index in range(len(data)-1, -1, -1):yield data[index]
for char in reverse('golf'):
...    print(char)
...
f
l
o
g

如前一节所述,可以用生成器完成的任何工作也可以用基于类的迭代器完成。使生成器如此紧凑的是,__iter__()__next__()方法是自动创建的。

另一个关键特性是在调用之间自动保存本地变量和执行状态。这使得函数比使用self.indexself.data等实例变量的方法更容易编写,也更清晰

除了自动创建方法和保存程序状态外,当生成器终止时,它们会自动引发StopIteration。结合使用这些特性,可以轻松创建迭代器,而无需花费比编写常规函数更多的精力。

生成器表达式

一些简单的生成器可以简洁地编码为表达式,使用类似于列表推导式的语法,但使用圆括号而不是方括号。这些表达式是为生成器立即被封闭函数使用的情况设计的。生成器表达式比完整的生成器定义更紧凑,但不太通用,而且往往比等价的列表推导式更有利于内存。

例子:

>>> sum(i*i for i in range(10))                 # sum of squares
285>>> xvec = [10, 20, 30]
>>> yvec = [7, 5, 3]
>>> sum(x*y for x,y in zip(xvec, yvec))         # dot product
260>>> unique_words = set(word for line in page  for word in line.split())>>> valedictorian = max((student.gpa, student.name) for student in graduates)>>> data = 'golf'
>>> list(data[i] for i in range(len(data)-1, -1, -1))
['f', 'l', 'o', 'g']

python学习笔记(7)—— 类相关推荐

  1. Python学习笔记 (类与对象)

    Python学习笔记 (类与对象) 1.类与对象 面向对象编程语言类: 一个模板, (人类)-是一个抽象的, 没有实体的对象: (eg: 张三, 李四) 属性: (表示这类东西的特征, 眼睛, 嘴巴, ...

  2. python面向对象编程72讲_2020-07-22 Python学习笔记27类和面向对象编程

    一些关于自己学习Python的经历的内容,遇到的问题和思考等,方便以后查询和复习. 声明:本人学习是在扇贝编程通过网络学习的,相关的知识.案例来源于扇贝编程.如果使用请说明来源. 第27关 类与面向对 ...

  3. Python 学习笔记13 类 - 继承

    我们在编程的过程中,并非都是要重头开始.比如其他人已经有现成的类,我们可以使用其他找人编写的类.术语称之为: 继承. 当一个类继承例外一个类时,它可以获得这个类的所有属性和方法:原有的类称之为 父类, ...

  4. Python学习笔记:类

    本文来自:入门指南 开胃菜参考:开胃菜 使用Python解释器:使用Python解释器 本文对Python的简介:Python 简介 Python流程介绍:深入Python 流程 Python数据结构 ...

  5. python学习笔记(面向对象,类)

    一.类的定义 1.类的基本结构 #命名规则: 驼峰法 class Student(): # 使用class 定义类a= 1 # 变量name = '小明'def aa(self): # 函数print ...

  6. python学习笔记:类的方法总结

    python中类的方法总结 在python中,类的方法有如下三种: (1)实例方法(即:对象方法) (2)类方法 (3)静态方法 下面,将对这三种方法进行总结. 1.实例方法(对象方法) 通常情况下, ...

  7. python学习笔记(类)

    类中一个常见的魔术方法 class pipei():def __init__(self,name,age,high): self.name = nameself.age = ageself.high ...

  8. Python 学习笔记12 类 - 使用类和实例

    当我们熟悉和掌握了怎么样创建类和实例以后,我们编程中的大多数工作都讲关注在类的简历和实例对象使用,修改和维护上. 结合实例我们来进一步的学习类和实例的使用: 我们新建一个汽车的类: #-*- codi ...

  9. Python学习笔记:创建分数类

    Python学习笔记:创建分数类 1.编写创建分数类.py # 创建分数类from math import gcd# 定义分数类 class Fraction: def __init__(self, ...

  10. Python学习笔记28:从协议到抽象基类

    Python学习笔记28:从协议到抽象基类 今后本系列笔记的示例代码都将存放在Github项目:https://github.com/icexmoon/python-learning-notes 在P ...

最新文章

  1. vs2008中常见错误解决方法汇总
  2. SDN控制器ONOS架构—Vecloud
  3. Data Mining 论文翻译:Deep Learning for Spatio-Temporal Data Mining: A Survey
  4. python selenium模拟键盘_SELENIUM自动化模拟键盘快捷键操作实现解析
  5. 目前机器学习最热门的领域有哪些
  6. linux 虚拟机大量udp请求失败_利用PXE远程装机服务批量部署Linux
  7. 中西造园水法浅比【ZZ】
  8. 如何将excel里的数据批量导入ACCESS,要用vb代码?
  9. 21个演示展示强大的jQuery特效
  10. 1、使用Keras构建图像分类器
  11. 基于python的车牌识别系统设计与实现
  12. 非参数中的秩和检验到底怎么做的?
  13. 线性代数学习笔记——第六讲——矩阵的转置
  14. 大手笔!舒印彪对核电发展表态,华能抢到了核电开发入场券!
  15. 【电脑技术】修改无线网卡MAC地址失败的原因
  16. 如何查看linux的日志
  17. 中断驱动的自行车码表
  18. hive支持update、delete
  19. android insert方法,史上最精炼android四大组件基础总结(忘记了的可以过一遍)
  20. 技术类电子书网站-影印文字版(https://itbook.download/)

热门文章

  1. 记一次安卓app上线应用宝
  2. ffmpge海康视频文件格式转换
  3. CCF 2019-12 第三题 化学方程式配平(100分)
  4. matlab创始时间,从 matlab 创始人 看 matlab | 学步园
  5. DTE和DCE的区分
  6. 网站服务器怎么配置,怎么配置自己的网站服务器
  7. python-ppt
  8. 边缘计算顶会SEC 2019论文速览(一)
  9. 全网去水印独立版带解析接口服务器打包带前端2.3版本(美化UI)
  10. 现代操作系统笔记 2.1 进程