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 论类命名空间

6.3 成员变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值