Python学习笔记
面向对象
类和对象
- 两个重要概念:类(class)和对象(object,也被称为实例,instance)
- 类是某一批对象的抽象,可以把类理解成某种概念。比如说全人类,这可以说成是一个类,是一个很大的范围,而类似于张三、李四这样的实例,就是具体的对象。
- 对象才是一个具体存在的东西。
定义类
- 语法:
class 类名:
执行语句……
零个到多个类变量……
零个到多个方法……
- 语法说明:
- 类体中的执行语句,会在定义类时自动执行
- 如果类体中没有任何代码,使用
pass
语句作为占位符。
- 下面的程序定义了三个类,来说明定义类的方法
class User:
"""
简单的User类
"""
print("User类")
print(help(User))
# Item类
class Item:
"""
简单的Item类
"""
print("Item")
# 在类空间中定义的变量,属于类变量。
_type = "11"
_color = "22"
class Book:
print("Book")
booktype = "IT图书"
# 在类中定义方法。
# 定义方法与定义函数几乎一样
# 实例方法第一个参数推荐使用self,有更好的可读性
def desc(self):
self.name = "lancibe"
self.price = 118
print("图书是%s,价格是%d" % (self.name , self.price))
- 如果想要使用类变量:
print("种类:%s" % Item._type)
print("颜色:%s" % Item._color)
python是动态语言
- Python类的类变量可以动态增加或删除:程序在类体为新变量复制就是增加类变量。所以
Item.foo = "新增变量"
就是增加了新的类变量。 - 程序也可以在任何地方为已有的类增加变量。
- 也可通过del语句删除已有类的类变量。
del Item._type
,删除之后就没有了,无法再进行访问。 - Python对象的实例变量也动态增加或删除:程序对新实例变量复制就是增加实例变量。
- 程序可以在任何地方为已有对象增加实例变量
- 也可通过del语句删除已有对象的实例变量。
实例方法
- 函数中定义的方法,默认是实例方法
- 实例方法第一个参数会被自动绑定到方法的调用者(该类的实例)——因此这些实例方法至少应该定义一个参数,该参数通常会被命名为self。
构造方法
- 构造方法是一个特殊的实例方法,方法名叫
__init__
- 创建对象是,自动调用构造方法。
- 如果开发者没有为该类定义任何构造方法,那么python会自动为该类定义一个只包含一个self参数的、默认的构造方法。
class Person:
# 构造方法
def __init__(self, name="lancibe", age=18):
print("构造方法")
self.name = name
self.age = age
class Teacher:
# 空类,只用一个pass语句
pass
创建对象
- python中类的作用有两个:
创建对象
和派生子类
。 - 创建对象就是调用构造器创建对象。
- 对象的作用:
- 操作对象的实例变量(包括访问实例变量的值、添加实例变量、删除实例变量)
- 操作对象的方法(包括调用方法,添加方法,删除方法)
p = Person()
# 这里是访问实例变量,应该使用.,表示对象.实例变量。
print(p.name, p.age)
p2 = Person("lancibe")
print(p2.name,p2.age)
p2 = Person(age = 18)
print(p2.name,p2.age)
p2 = Person("Lan", 19)
print(p2.name,p2.age)
- 这样的输出结果是
构造方法
lancibe12 20
构造方法
lancibe 20
构造方法
lancibe12 18
构造方法
Lan 19
- 这说明了以下几点:
- 创建对象时,调用了构造器,访问了一遍构造器中的所有内容
- 定义了方法之后,除了第一个参数一般默认写
self
之外,其他参数都可以不进行初始化,但是进行初始化表示如果没有对该参数赋值,初始值就是默认的。 - 可以使用关键字参数的形式传入。
- 访问实例变量不要忘记
.
- 构造方法是用于初始化对象的实例变量
- 如果写了
t = Teacher(name = "lancibe")
,系统就会报错,因为Teacher是一个空类,没有定义构造器,因此它只有一个只带self参数的构造方法。 - 也就是说,想要传入参数,必须创建自己的构造方法。
- 调用构造方法是调用类名,不是直接调用
__init__
方法
对象的作用
- 操作对象的实例变量,这包括了访问、赋值、添加、删除实例变量
- 操作对象的方法,这包括了调用、添加、删除方法。
对实例变量的操作
- 首先定义一个类
class Item:
def __init__(self, name = "lancibe"):
self.name = name
- 访问和赋值:
im1 = Item()
print(im1.name)
# 下面是对实例变量进行重新赋值
im2 = Item()
im2.name = "faker"
print(im2.name)
-
这样的结果就是
lancibe
和faker
。 -
新增实例变量
-
由于python是动态语言,所以新增实例变量就是对不存在的变量赋值:
im3 = Item()
im3.color = "黑色"
print(im3.color)
-
这样的结果是
黑色
,这说明新增实例变量成功。 -
删除实例变量
-
使用
del
语句来删除,我们可以通过检查是否还能再次访问来判断是否删除成功。
# 删除实例变量
del im2.name
print(im2.name)
对实例方法的操作
- 调用方法:
class Item:
# 实例方法是属于对象的,因此用对象调用
def test(self):
print("test")
im = Item()
im.test()
- 输出结果是test
- 新增方法,这一部分可能比较难以理解,作为难点。
# 新增的方法默认是不会绑定self的,换言之,self参数必须手动传入
def func(self):
print("新增的方法")
im2 = Item()
im2.foo = func
im2.foo(im2)
- 这种方式非常奇怪,但其实也没有任何问题,我们先调用了构造器,说明变量
im2
是一个Item()
类的一个对象,再访问新的方法,默认也就创建了一个新的方法,同时这个方法是调用了函数func,最后在进行方法的调用时,要加上参数,参数名就可以直接写变量名本身。 - 为了便于理解,python可以通过
from
语句来调用types
进行操作。
# 这一行也可以使用import types,不过这样的话,下面的调用应该写成types.MethodType
from types import MethodType
# 将func函数包装成方法,且im自动绑定第一个参数
im.bar = MethodType(func, im)
im.bar()
- 删除方法
- 删除方法可以删除我们新增的方法:
del im2.foo
- 删除后就无法再访问了,如果访问,系统会报错
AttributeError: 'Item' object has no attribute 'foo'
。 - 还可以以方法赋值:
import types
# 为该实例变量赋值,但所赋的是方法
# 因此该实例变量就是变成了方法
im2.color = types.MethodType(func, im2)
im2.color()
- 我们可以知道,python中,一个变量到底是实例变量还是方法是不一定的,是可以来回转换的,取决于实例变量的值
总结
- 动态增加的方法:Python不会自动将方法调用者绑定到他们的第一个参数
- 如果动态增加的方法也能自动昂绑定第一个参数,可借助types模块下的
MethodType
进行包装。