文章目录
类和对象
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)