面向对象
目录
💼前言
从没见过谁把面向对象写的这么详细的--持续更新中!!!✨
本文详细介绍了面向对象的用法,并且用了很多例子来进行介绍,方便你们理解。🌈
🍎一、基本语法
👇🏽 👇🏽 👇🏽
这里讲解了面向对象的基本使用方法☀️
定义类
1. class 类名:
2. class 类名(object):
class Student(object): # 关注这个类有哪些特征值和行为
# 在 init方法里面 以参数的形式定义属性 我们也称之为 属性
def __init__(self,name,age,height):
self.name = name
self.age = age
self.height = height
# 行为定义为 一个个的函数
def play(self):
print('{}正在打游戏'.format(self.name))
def eat(self):
print('{}正在吃饭'.format(self.name))
# 使用Student类 创建了2个实例对象 s1 s2
# s1,s2 都会有 name,age,height 属性 和 run和eat方法
s1 = Student('张三',18,1.8) #会自动调用 init方法
s2 = Student('李四',17,1.9)
# 根据需求 让不同对象 执行不同行为
s1.play()
s1.eat()
s2.eat()
🍏二、self语句以及__slots__
👇🏽 👇🏽 👇🏽
这里的方法和self语句 使用方法如注释所说☀️
class Student(object):
# 这个属性直接定义在类里面, 是一个元组,用来规定对象可以存在的属性 这里面写了属性才能够使用 没有写的属性 是会报错的
__slots__ = ('name','age')
def __init__(self,x,y):
self.name = x
self.age = y
def say_hello(self):
print('大家好我是:',self.name)
s1 = Student('张三',18)
# 运行上面这段代码 会发生什么
# 1. 调用__new__ 方法 , 这个方法就是用来申请内存空间的
# 2. 调用__init__ 方法, 并让self指向申请好的内存空间
# 3. 让s1指向创建好的内存空间
# 这个就是谁调用 say_hello 就是谁调用say_hello的内存
s1.say_hello()
# # 下面这种叫动态属性
# print(s1.height)
# # 结果是 AttributeError: 'Student' object has no attribute 'height'
# # 没有这个属性会报错
# 下面这个前提是 没有写 __slots__方法的情况下是可以这样写 如果写了 __slots__方法 并且方法没有city 那么就无法使用 会报错
# # 但是如果这样
# s1.city = '深圳'
# print(s1.city)
# # 直接使用等于号 给一个属性赋值
# # 如果这个属性以前不存在 会给对象添加一个新的属性
# # 如果这个属性以前存在 会给对象修改属性对应的值
🍐三、__init__魔法方法以及一些其他魔法方法
👇🏽 👇🏽 👇🏽
魔法方法,也叫魔术方法,是类里的特殊的一些方法
特点: 不需要手动调用,会在合适的时机自动调用
这些方法都是使用 __开始 __结束
方法名都是系统规定好的 在合适的时机自己调用
class Person(object):
# 在创建对象的时候,会自动调用这个方法
def __init__(self,name,age):
print('init被调用了')
self.name = name
self.age = age
# 这个当对象被销毁的时候 会自动调用这个方法
def __del__(self):
print('del方法被调用了')
# 这个下面没有销毁这个对象为什么会调用 因为 程序运行结束了 这个对象就被自动销毁了 所以会调用
def __repr__(self):
return 'hello'
def __str__(self):
return 'good'
def __call__(self, *args, **kwargs):
# print('call方法被调用了')
fn = kwargs['fn']
return fn(args[0],args[1])
p = Person('zhangsan',18)
# print(p)
# 直接打印p 如果不做任何修改 直接打印一个对象 打印的是对象的__name__类型和内存地址
# 当打印一个对象的时候,会调用这个对象的__str__ 或者 __repr__方法
# 那我们重写一下 __repr__
# print(p)
# 就会输出hello
# 那么我们 2个都重写 这个只会选择 __str__ 调用
# print(p)
# 会输出good
# 魔法方法都是自己调用的 当然我们可以手动调用
# print(repr(p))
# 这样调用也可以 print(p.__repr__())
# 会输出 hello
# 这个选择的话 一般选择 str
# 用一个魔法方法 让这个p 能够直接被调用
# 使用 __call__方法
# p()
# 输出call方法被调用了
# 这个其实就是变成了对象名 调用call方法
# 这里一个小案例
n = p(1,2,fn=lambda x,y:x+y)
print(n)
# 这种传参的 上面是return 这里需要 让一个等于他 然后再输出
🍊四、运算符相关的魔法方法
👇🏽 👇🏽 👇🏽
此处使用的是运算符相关的魔法方法,都是与运算符有关的☀️☀️
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def __eq__(self, other):
return self.name == other.name and self.age == other.age
# == 运算符本质其实是调用对象的__eq__方法
def __gt__(self, other):
return self.age > other.age
# 这个返回值的意思就是 p1 p2 对象 会比较年龄的大小
# 外面使用大于号就会自动调用这个方法
# def __ge__(self, other):
# 用这个就是 使用大于等于号会调用这个方法
# def __lt__(self, other):
# 这个是使用小于运算调用
# def __le__(self, other):
# 这个是使用小于等于调用的
def __add__(self, other):
# 加法会调用这个
return self.age + other.age
def __sub__(self, other):
# 减法会调用这个
return self.age - other.age
# 只写个 other 就可以 减数字 不减对象
def __mul__(self, other):
# 这个是乘法调用
return self.name * other.age
# def __truediv__(self, other):
# 除法运算调用
p1 = Person('张三',18)
p2 = Person('张三',19)
# == 运算符本质其实是调用对象的 __eq__方法 获取__eq__方法的返回结果
# a == b => a.__eq__(b)
print(p1 == p2) # True
# != 本质是调用 __ne__方法 或者 __eq__ 方法取反
# 也就是 如果写了 ne方法就调用 ne 方法 没写ne方法 就是 __eq__取反
print(p1 != p2) # False
# 然后 这个本身是不支持 大于运算的 需要写一个 __gt__方法
print(p1 > p2)
# str() 转换对象 转换为字符串 会自动调用__str__方法
# 打印对象也会调用 __str__
print(str(p1)) # 转换成为字符串 默认会转换成类型+内存地址
# 转换int是会调用 __int__方法
# float 调用 __float__方法
# 特殊情况
print(int(p1)) #只调用了 __int__ 没有调用 __str__
🍋五、内置属性
👇🏽 👇🏽 👇🏽
内置属性指的是python本身内置的并不是外界导包加入的☀️
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self):
print(self.name + '正在吃饭')
p = Person('张三',18)
# 内置属性 dir 可以查看 对象的所有支持的属性和行为
print(dir(p))
# p.__dict__ 可以把属性和值转换成字典
print(p.__doc__)
# 这个是可以拿到类里面的文档注释
# print(Person.__doc__) 用类名也可以拿到注释
print(p.__module__) # 这个是可以拿到模块名称
🍌六、将对象当做字典操作
👇🏽 👇🏽 👇🏽
想要将对象当成字典使用需要用到以下方法☀️☀️
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def __setitem__(self, key, value):
# print('key={},value={}'.format(key,value))
# 使用[ ] 语法 会调用 这个方法
p.__dict__[key] = value
def __getitem__(self, item):
return self.__dict__[item]
p = Person('张三',18)
print(p.__dict__) # 把对象转为字典
# 能转字典 但是不能把对象当作字典使用
p['name'] = 'jack'
# [ ]语法会调用对象的 __setitem__方法
# 那么如果要把对象做字典的那种感觉就设置 __setitem__ 就可以使用 字典的修改方法 修改 对象
print(p.name)
# 怎么样能够 像字典一样获取值 使用字典的方法获取值 会调用 __getitem__方法
print(p['name'])
🍉七、类属性和对象属性
👇🏽 👇🏽 👇🏽
class People(object):
type = '人' # 这个类属性定义在类里 函数之外 我们称之为类属性
def __init__(self,name,age):
self.name = name
self.age = age
# 对象p 是实例对象 People称之为 类对象
# name和age 是对象属性 是每一个实例对象都会单独保存的一份属性 是在__init__方法里 以参数的形式定义的
# 每个实例对象之间的属性没有关联,互不影响
p = People('张三',18)
p2 = People('李四',19)
# 类属性可以通过类对象和实例对象获取
print(People.type) # 可以通过类对象获取类属性
# 可以通过 实例对象获取类属性
print(p.type)
# 类属性只能通过类对象来修改,实例对象无法修改类属性
p.type = 'human'
# 这样不是修改 类属性 只是在p中 加了一个 type = 'human'
# People.type = 'human'这样就是修改了类属性
🌟🌟🌟🌟文章持续更新中!!!!🌟🌟🌟🌟