面向对象
内容
- 类
- 对象
- 属性 --> 名词、形容词:状态
- 方法 --> 动词 :动作
类名 : 首字母大写 + 驼峰式命名
ValueError TypeError StopIterator
- 所有的类 继承 祖宗类: Object类
定义
class Phone(object): # python2 必须
pass
class Phone(): # python3 默认object
pass
class Phone: # () 也可以省略
pass
class XiaoMi(Phone): # (父类)
# 属性
# 方法
空类 也可 动态添加属性
- 区别 类属性 和 对象属性
# 定义类和属性
class Student(object):
# 类属性
name = 'Jam'
age = 24
s1 = Student()
print(s1.name) # 首先 判断 s1 有没有name 属性, 没有 则去 类中 取对应的 类属性(初始值)
s1.age = 2
print(s1.age) # 首先 判断 s1 有没有age 属性,此时的 age 属性 被重新赋值过, 因此它是 s1的 对象属性
try:
print(s1.sex)
except AttributeError as ae:
print(ae, 'and add it!')
s1.sex = 0 # 新增 对象属性
# 类属性 通过类名 使用
Student.name = 'Null'
s2 = Student()
print(s2.name)
-
类中的方法
- 普通方法
- 魔术方法一:
- 共性特征
- 不同于类属性
- 类方法
- 静态方法
class xxx():
def __init__(self):
self.price = 2999
# init 传值
class xxx(object):
def __init__(self, price):
self.price = price
ooo = xxx(35) # 传参 实例化
面向对象实践:
# cat
class Cat(object):
type = '猫'
type_en = 'cat'
def __init__(self, nickname, age, color):
self.nickname = nickname
self.age = age
self.color = color
def eat(self, food):
print('{}喜欢吃{}'.format(self.nickname, food))
def catch_mouse(self, weight, color):
print('{} 抓了一只{}kg的{}老鼠!'.format(self.nickname, weight, color))
def sleep(self, hour):
if hour < 5:
print('需要睡觉!')
else:
print('可以工作!')
def show_info(self):
print('正在打印 详细信息')
print(self.nickname, self.age, self.color)
cat_1 = Cat('花花', 2, '灰色')
cat_1.catch_mouse(0.5, '黑色')
cat_1.sleep(8)
cat_1.eat('小鱼干')
类方法
认识、了解 即可
- 特点:
- 定义需要依赖装饰器
- 自动传入的参数不是对象,是类
- 类方法中只可以使用类属性,不可以使用
- 在创建完成类,实例化对象之前,类方法已经写入类内存
- 类方法 不能调用 普通方法 - 同级普通方法可以互相调用
- 作用
只能访问类属性 和 类方法,使用于 需要 创建对象 之前完成的动作,
# 类方法
# 类方法
class Dog(object):
__age = 2
def __init__(self, nickname): # 魔术方法 依赖于self(这个对象)
self.nickname = nickname
def run(self): # 普通方法 依赖于self
print('run')
@classmethod # 类方法 前面加 @classmethod
def test(cls): # 自动传入 cls(这个类)
__age += 1
print(cls.__age)
# print(self.run())
# print(cls.nickname) # AttributeError:
Dog.test()
d = Dog('DaHuang')
# Dog.__age
# d.__age
d.run()
d.test(d)
私有变量
class Person():
__age = 18
静态方法
class Person():
__age = 18
def __init__(self):
self.name = 'jack'
@staticmethod
def static_func():
# 不能访问 对象属性 不能出现 self
# 可以访问 类属性,但不通过 cls
print(Person.__age)
- 静态方法 与 类方法相似
- 由 @staticmethod 定义
- 能 通过类名 访问类属性
- 不能使用 self、cls 参数
- 加载时机 同 类犯法
-
静态 和 类方法 很少写到,认识了解即可
-
面试可能会问,读源码可能会出现
-
相同:
- 都只能访问类的属性和方法,对象的无法访问
- 都可以通过类名调用
- 都在对象实例化之前创建 因此不依赖于对象
- 不同:
- 装饰器不同
- 类方法自带传入cls参数,静态方法默认无传参
- 普通方法 与 两者的区别
- 普通 无装饰器
- 依赖于对象 self
- 只有实例化对象后 才能调用普通方法
魔术方法
魔术方法就是类/对象中的一个方法
区别在于普通方法需要调用
魔术方法是在特定时刻自动触发
import sys
class MagicFunc():
param = 'Para'
def __new__(cls, *args, **kwargs):
print('__new__')
"""
实例化:
系统默认 存在__new__方法 用于 为实例化对象 申请开辟内存空间
重写 __new__ 则不会自动为新对象开辟新地址,从而导致 __init__ 不被调用
return 开辟的地址
"""
r = object.__new__(cls, *args, **kwargs)
print(r)
return r
def __init__(self):
print('__init__')
"""
初始化
对象实例化后,为其初始化
"""
print(self)
def __call__(self, *args, **kwargs):
print('__call__') # 将对象当作函数p() 来使用时触发
print(*args)
def __del__(self):
print('__del__')
"""
1. 对象赋值
析构
:return:
"""
print(self)
def __getattr__(self, item):
pass
mf = MagicFunc()
mf('hello','hi')
mf('hello')# 触发__call__
mf_c1 = mf # 克隆mf 将内存空间地址赋值
mf_c2 = mf # clone mf
del mf_c1 # 删除 mf_c1 ,断开与 mf 的链接
del mf_c2
print(sys.getrefcount(mf)) # 查看mf 内存空间 被使用几次,包含本次