一、 基本概念
1. 对象
--- 有具体行为和属性的东西
2. 类
--- 将需求的对象划分为不同的类,具有相同属性或者行为的对象划分为一个类
3. 类和对象之间的关系
--- 类是模板,对象是根据类创建的实例
类是对象的抽象,对象是类的具体实现
> 开发从对象开始分析 -- 将对象分类 - 考虑每个类都有什么样的属性和行为
二、 定义和初始化
1. 类的定义
class 类名[(default = object)]:
'注释'
类体
对象名 = 类() # 括号中是否有参数,取决于init方法
eg.
class Person:
pass
p1 = Person()
#打印对象
perint(p1)
#查看对象对应类注释
print(p1.__doc__)
2. 类的属性和行为
属性: 变量绑定的形式
行为: 函数定义的形式
2.1 动态创建
(1) 动态定义属性
① 创建对象
② 对象.属性名 = 属性值
p1.name = '张珊'
p1.age = 23
print()
(2) 动态定义行为
① 创建对象
② 创建方法
③ 对象.方法()
eg.
def run (self):
print('我在跑步')
p1.run = run
p1.run(p1)
p2 = Person()
> 动态创建属性和行为的局限性:
—— 每一个对象都要赋予属性和方法
—— 动态增加的属性与方法仅对当前对象有效
2.2 定义类中的属性和方法
--- 给实例定义属性和实例定义方法
(1) 定义实例方法
--- 在类中定义的self,代表当前对象
eg.
class Person:
# 类属性
desc = '人的描述'
# 类方法
@classmethod
def copy_person(cls, old):
print('类方法执行')
return cls(old.name, old.age)
# init实例初始化方法---简化对象初始化
def __init__(self, name, age):
print('执行init方法')
# 定义实例属性,弱类型用None
self.name = 'name'
self.age = age
self.weight = None
# 定义实例方法
def fun(self, place):
# wei还没有赋值
print('{}在{}跑步中,她{}岁,'.format(place, self.name, self.age))
# 强类型属性
p1 = Person('张珊', 23)
# 弱类型属性
p1.wei = 90
# 复制对象
p2 = Person.copy_person(p1)
(2) 定义实例属性
--- 推荐统一在init实例方法中定义,init方法中初始化属性,但不是创建
注意: init方法添加的属性一定要是强类型属性
(3) 类的成员
实例属性 实例方法
类属性 类方法
静态方法
1> 类属性: 和对象无关,和实例相关 --- 所有实例共有
2> 实例属性: 和实例无关,和对象相关 --- 所有实例共有
eg.
class Person:
# 类属性
desc = '人的描述'
# 初始化
def __init__(self, name, age):
delf
① 访问方式:
实例属性: a 实例.实例属性
类属性: b 类.类属性(推荐)
c 实例.类属性
eg.
p1 = Person('张珊')
print(Person.desc)
print(p1.desc)
② 修改
类.类属性 可以修改
实例.实例属性 不能修改,只会在实例下创建一个新的实例属性
eg.
p1 = Person('张珊')
Person.desc = '人的描述_new:' # 通过类访问
p1.desc = '人的描述_new:' # 通过对象访问
p2 = Person('Geoffrey')
print(Person.desc, p1.desc, p2.desc)
> 类属性的应用: 定义所有对象都共用的属性
eg.
class Pubclass:
department = '光环'
def __init__(self, name):
pass
3> 实例方法
--- 跟实例相关,和类无关 ,实例独享
4> 类方法
--- 和实例无关,跟类有关,实例共享
添加装饰器@classmethod
① 访问方式:
类方法访问: 类.方法 实例.方法
实例方法访问: 实例.方法 类.方法(不推荐)
② 应用:
创建、 复制对象
(4) 类属性和实例属性的相互调用
eg.
class Person:
# 类属性
desc = '人的描述'
# 类方法
@classmethod
def copy_person(cls, old):
print('类方法执行')
return cls(old.name, old.age)
# 静态方法
@staticmethod
def makefriend(p1, p2):
函数体
print('{}和{}是死对头'.format(p1, p2))
print('静态方法执行')
# init实例初始化方法---简化初始化对象
def __init__(self, name, age):
print('执行init方法')
# 定义实例属性,弱类型用None
self.name = 'name'
self.age = age
self.weight = None
# 定义实例方法
def fun(self, place):
# wei还没有赋值
print('{}在{}跑步中,她{}岁,'.format(place, self.name, self.age))
① 类方法 访问 类属性
> Person.desc
> cls.desc(推荐)
② 实例方法 访问 类属性
> Person.desc
> self.__class__.desc(推荐)
③ 类方法 访问 实例属性
> 不合理, 类方法不能针对单独实例,(但是不是不能,加参数)
④ 实例方法 访问 实例属性
> 使用self
(3) 静态方法
--- 相当于类外面的函数,放在了类体里(面向对象)
@staticmethod
def sm():
print('静态方法执行')
> 静态方法的访问 --- 通过类名
Person.sm
> 应用场景:
---静态方法只是定义在类的内部,从逻辑结构上,与当前类划分到了一起,从功能的角度讲,我们完全可以将静态方法迁移到类的外部,作为函数来实现同样的功能。
总结 --- 类和实例的选择:
1. 类属性 和 实例属性:
分析是所有对象共享还是单独对象独享
2. 类方法、实例方法、静态方法:
分析方法是为什么属性服务,如果是操作实例,定义成实例方法...
如果单独作用,静态方法
(4) 魔法方法
格式: __XXX__
> 当符合条件时,自动调用
> 一般不自己创建,因为不能自动调用
① __new__(cls, *args, **kwargs)
--- 静态方法,且不需要用staticmethod装饰器
在创建对象时候执行
在方法中必须有return,否则init方法无法初始化,不能创建对象
eg.
class Person:
def __init__(self, name, age):
print('执行init方法')
# 定义实例属性,弱类型用None
self.name = 'name'
self.age = age
# __new__已经继承了object,实际为重写
def __new__(cls, *args, **kwargs)
# 继承
return super().__new__(cls)
def __str__(self):
print('修改了__str__方法')
return 'name:{},age:{}'.format(self.name, self.age)
def __bytes__(self):
return b'bytes person class'
p1 = Person()
print(p1) 相当于 print(p1.__str__())
② __init__ (self)
--- 实例方法,初始化对象
③ __del__
--- 实例方法,当启动垃圾回收机制回收对象时调用
④ __str__
--- 实例方法,调用内建函数如str,format或print时,返回的str描述
⑤ __rper__
--- 和__str__方法相同,但是更接近机器,优先级低于__str__;
用来以字节的形式描述对象
⑥ __bytes__
--- 转化为字节,用来以字节的形式描述对象
(5) 动态属性操作
① hasattr(obj, name)
--- 判断obj对象中是否已经存在(name)属性名,返回bool
② setattr(obj, name, value)
--- 将obj的name属性赋值value
③ getattr(obj, name)
--- 将obj对象中的name属性取出
④ delattr(obj, name)