Python 学习笔记 4:——Python中的类、对象与迭代器

类和对象

Python 是一种 面向对象 的编程语言。
Python 中的几乎所有东西都是对象,拥有 属性和方法
类(class)类似对象构造函数,或者是用于创建对象的“蓝图”。
Python 创建类时,使用 class 关键字:

class MyClass:
	x = 5
p1 = MyClass()
print(p1.x)

具体而言,类(Class) 是用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象 是通过类定义的数据结构实例,包括两个 数据成员(类变量和实例变量,用于处理类及其实例对象的相关的数据)和 方法(类中定义的函数)。
创建一个类的实例,类的具体对象,称为 实例化

类变量 在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外;类变量通常不作为实例变量使用。
在类的声明中,属性是用变量来表示的,这种变量就称为 实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。

如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫 方法的覆盖(override),也称为 方法的重写。定义在方法中的变量称为 局部变量,只作用于当前实例的类。

函数

__init__() 函数

所有类都有一个名为 __init__() 的函数,它始终在启动类时执行。
使用 __init__() 函数将值赋给对象属性,或者在创建对象时需要执行的其他操作。

class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age

p1 = Person("Bill", 63)
print(p1.name)  #  Bill
print(p1.age)   #  63

每次使用类创建新的对象时,都会 自动调用 __init__() 函数。

子的 __init__() 函数会覆盖对父的 __init__() 函数的继承;添加 __init__() 函数时,子类将不再继承父的 __init__() 函数。

# Student 类是 Person 的一个子类
class Student(Person):
  def __init__(self, fname, lname):
    # 添加属性等

如需保持父类的 __init__() 函数的继承,需要添加对父类的 __init__() 函数的调用。

# Student 类是 Person 的一个子类
class Student(Person):
  def __init__(self, fname, lname):
    Person.__init__(self, fname, lname)

super() 函数

Python 有一个 super() 函数,它会使子类从其父类继承所有方法和属性。

class Student(Person):
  def __init__(self, fname, lname):
    super().__init__(fname, lname)

对象方法

对象也可以包含方法。对象中的方法是属于该对象的函数。

class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age

  def myfunc(self):
    print("Hello my name is " + self.name)

p1 = Person("Bill", 63)
p1.myfunc()  # Hello my name is Bill

self 参数

self 参数是对类的当前实例的引用,代表当前对象的地址,用于访问属于该类的变量。
self.__class__ 则指向类。
它不必被命名为 self,您可以随意调用它,但它必须是类中 任意函数的首个参数

class Person:
  def __init__(mysillyobject, name, age):
    mysillyobject.name = name
    mysillyobject.age = age

  def myfunc(abc):
    print("Hello my name is " + abc.name)

p1 = Person("Bill", 63)
p1.myfunc()  # Hello my name is Bill

下划线说明

__foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 __init__() 之类的。
_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *
__foo: 双下划线的表示的是私有类型( private )的变量, 只能是允许这个类本身进行访问了。

Python内置类属性

__dict__ : 类的属性(包含一个字典,由类的数据属性组成);
__doc__ : 类的文档字符串;
__name__: 类名;
__module__: 类定义所在的模块(类的全名是 ‘__main__.className’,如果类位于一个导入模块 mymod 中,那么className.__module__ 等于 mymod);
__bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)。

删除对象或对象属性

可以使用关键字 del 删除对象和对象的属性:

del p1.age
# or
del p1

Python 使用了引用计数这一技术来跟踪和回收垃圾。
在 Python 内部记录着所有使用中的对象各有多少引用。
一个内部跟踪变量,称为一个引用计数器。
当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时, 也就是说, 这个对象的引用计数变为0 时, 它被垃圾回收。但是回收不是"立即"的, 由解释器在适当的时机,将垃圾对象占用的内存空间回收。

垃圾回收机制不仅针对引用计数为0的对象,同样也可以处理循环引用的情况。循环引用指的是,两个对象相互引用,但是没有其他变量引用他们。这种情况下,仅使用引用计数是不够的。Python 的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器。作为引用计数的补充, 垃圾收集器也会留心被分配的总量很大(即未通过引用计数销毁的那些)的对象。 在这种情况下, 解释器会暂停下来, 试图清理所有未引用的循环。

pass 语句

类定义不能为空,但是如果您处于某种原因写了无内容的类定义语句,请使用 pass 语句来避免错误。

class Person:
  pass

继承

继承允许我们定义继承另一个类的所有方法和属性的类。
父类是继承的类,也称为 基类
子类是从另一个类继承的类,也称为 派生类

任何类都可以是父类,因此语法与创建任何其他类相同。

class Person:
  def __init__(self, fname, lname):
    self.firstname = fname
    self.lastname = lname

  def printname(self):
    print(self.firstname, self.lastname)

# 使用 Person 来创建对象,然后执行 printname 方法:
x = Person("Bill", "Gates")
x.printname()

要创建从其他类继承功能的类,需要在创建子类时将父类作为参数发送。

# 创建一个名为 Student 的类,它将从 Person 类继承属性和方法:
# 使用 pass 关键字,没有向该类中添加任何其他属性和方法;
# Student 类拥有与 Person 类相同的属性和方法。
class Student(Person):
  pass

如果在子类中添加一个与父类中的函数同名的方法,则将覆盖父方法的继承。

迭代器

Python 中的迭代器是实现迭代器协议的对象,该对象包含值的可计数数字,包含方法 __iter__()__next__()
Python 中的列表、元组、字典和集合都是可迭代的对象,有获取迭代器的 iter() 方法。

mytuple = ("apple", "banana", "cherry")
myit = iter(mytuple)
print(next(myit))  # apple
print(next(myit))  # banana
print(next(myit))  # cherry

Python 中的字符串也是可以迭代的对象,包含一系列的字符,并且可以返回迭代器:

mystr = "banana"
myit = iter(mystr)

print(next(myit))  # b
print(next(myit))  # a
print(next(myit))  # n
print(next(myit))  # a
print(next(myit))  # n
print(next(myit))  # a

创建迭代器

要把对象/类创建为迭代器,必须为对象实现 __iter__()__next__() 方法。

# 创建一个返回数字的迭代器,从 1 开始,每个序列将增加 1(返回 1、2、3、4、5 等):
class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self

  def __next__(self):
    x = self.a
    self.a += 1
    return x

myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter))  # 1
print(next(myiter))  # 2
print(next(myiter))  # 3
print(next(myiter))  # 4
print(next(myiter))  # 5

StopIteration

如果有足够的 next() 语句,或者在 for 循环中使用,则上面的例子将永远进行下去。
为了防止迭代永远进行,我们可以使用 StopIteration 语句。
__next__() 方法中,如果迭代完成指定的次数,我们可以添加一个终止条件来引发错误:

class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self

  def __next__(self):
    if self.a <= 20:
      x = self.a
      self.a += 1
      return x
    else:
      raise StopIteration

myclass = MyNumbers()
myiter = iter(myclass)
for x in myiter:
  print(x)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值