Python学习-第六章-类与对象
6.1 类与对象
6.1.1 定义类
Python定义类的简单语法如下:
class 类名:
执行语句...
零个到多个类变量...
零个到多个方法...
- 在类中定义的方法默认是实例方法,定义实例方法的方法与定义函数的方法基本相同,只是实例方法的第一个参数会被绑定到方法的调用者(该类的实例)------因此实例方法至少应该定义一个参数,该参数通常会被命名为self。
- 在实例方法中的__init__,这个方法被称为构造方法。构造方法用于构造该类的对象,无须使用new调用构造方法返回该类的对象
class Person:
hair='black'
def __init__(self,name='charlie',age=8):
self.name=name
self.age=age
def sayHi(self,content):
print(content)
6.1.2 对象的产生和使用
p=Person()
print(p.name,p.age)
p.name='liuan'
p.sayHi('hello,world!')
print(p.name,p.age)
6.1.3 对象的动态性
动态添加变量
程序可以动态为p对象增加实例变量,只要为它的新变量赋值即可,也可以动态删除实例变量(del)。
# 增加实例变量
p.skill=["fishing","dancing"]
print(p.skill) # ['fishing', 'dancing']
# 删除实例变量
del p.name
print(p.name) # AttributeError: 'Person' object has no attribute 'name'
动态添加函数
动态添加的函数不会将调用者绑定到第一个参数(一般叫self),需要手动绑定
def eatSomething(self,content):
print("eat "+content)
p.eatSomething=eatSomething
# 手动绑定调用者到第一个参数
p.eatSomething(p,"banana")
print(p.eatSomething) # eat banana
或者可以引入MethodType绑定
def singSong(self,content):
print("sing "+content)
from types import MethodType
p.singSong=MethodType(singSong,p)
p.singSong="爱你一万年"
print(p.singSong)
6.1.4 实例方法和自动绑定
- self参数出现在构造方法中引用该构造方法正在初始化的对象
- self参数出现在实例方法中引用调用该方法的对象
class Dog:
def jump(self):
print("正在执行jump方法")
def run(self):
self.jump()
print("正在执行run方法")
dog=Dog()
dog.run()
上面代码中的run()方法中的self代表该方法的调用者,self不能省略.
当self参数作为对象的默认引用时,程序可以像访问普通变量一样来访问这个self参数,可以将self参数当作实例方法的返回值
class ReturnSelf:
def grow(self):
if hasattr(self,'age'):
self.age+=1
else:
self.age=1
return self
rs=ReturnSelf()
rs.grow().grow().grow()
print(rs.age)
6.2 方法
6.2.1 类也能调用实例方法
以下通过类直接调用实例方法,错误代码:
class Dog:
def jump(self):
print("正在执行jump方法")
def run(self):
self.jump()
print("正在执行run方法")
Dog.run()
TypeError: run() missing 1 required positional argument: 'self'
调用run方法缺少self参数的传入,所以报错.
说明使用类调用实例方法,python不会自动绑定self参数.必须手动为方法的第一个参数传入参数值
class Dog:
def jump(self):
print("正在执行jump方法")
def run(self):
self.jump()
print("正在执行run方法")
dog=Dog()
# 显示地为方法的第一个参数绑定参数值
Dog.run(dog)
这种调用方式成为“未绑定方法”
6.2.2 类方法与静态方法
使用@classmethod修饰类方法,python自动绑定方法第一参数
使用@staticmethod修饰静态方法,python不会自动绑定第一参数,手动指定
class Bird:
@classmethod
def fly(cls):
print("类方法fly:"+str(cls))
@staticmethod
def info(p):
print("静态方法info:"+p)
Bird.fly()
Bird.info("vvvvvvv")
使用了@staticmethod定义的静态方法,既可以使用类调用又可以使用对象调用,不管哪种调用方式,都不会为静态方法自动绑定第一参数.
6.2.3 @函数装饰器
使用@符号引用已有的函数后,可用于修饰其他函数,可开发自定义的函数装饰器.
过程为以下两个步骤:
- 将被修饰的函数B当作参数传入@符号引用的函数A中
- 将函数B替换为上一步的返回值
def funA(fn):
print("A")
fn()
return "acdf"
@funA
def funB():
print("B")
print(funB)
result:
A
B
acdf
如果修饰函数返回的是函数,则B被替换后还是函数:
def foo(fn):
def bar(*args):
print("===1===",args)
n=args[0]
print("===2===",n * (n-1))
print(fn.__name__)
fn(n*(n-1))
print("*" * 15)
return fn(n * (n-1))
return bar
@foo
def myTest(a):
print("==mytest函数==",a)
myTest(6,5)
这里,B被替换为bar函数
result:
===1=== (6, 5)
===2=== 30
myTest
==mytest函数== 30
***************
==mytest函数== 30
实际用处:
- 可以在被修饰函数钱添加一些额外的处理逻辑(比如权限检查)
- 可以在被修饰函数后添加一些额外的处理逻辑(如记录日志)
- 还可以在目标方法抛出异常时进行一些修复操作
类似于Java中的AOP切面编程(自己的感受)
6.2.4 论类命名空间
…