面向对象的程序开发
"""
用几大特征表达一类事物称为一个类,类更像是一张图纸,表达的是一个抽象概念
对象是类的具体实现,更像是由这图纸产出的具体物品,类只有一个,但对象可以通过这个类实例化出多个
对象是类的实例,类是对象的模板
*类中的成员只有方法和属性,不要裸露的把判断和循环直接写在类中,而是用方法包起来
(1)类的定义
(2)类的实例化
(3)类的基本结构
(4)类的命名
"""
1. 类的定义
# 1
class Car:
pass
# 2 推荐
class Car():
pass
# 3.
class Car(object):
pass
2. 类的实例化
class Car():
pass
obj = Car()
print(obj)
3. 类的基本结构
"""
类中两样东西:
(1)成员属性
(2)成员方法
"""
class Car():
# 成员属性
color = "白色"
# 成员方法
def didi():
print("小车会滴滴的叫")
# 语法上不报错,但是严禁使用,破坏了类中的结构,不要裸露的把判断和循环直接写在类中,而是用方法包起来
class Car():
if 5 ==5 :
print(11223344)
4. 类的命名
"""类的命名 : 推荐使用大驼峰命名法,每个单词的首字母都要大写"""
"""
mycar => MyCar
zhangbaozhang => ZhangBaoZhang
"""
面向对象三大特征: 封装 继承 多态
封装
对类中成员属性和方法的保护,控制外界对内部成员的访问,修改,删除等操作
对象的操作
"""
封装:
1.私有 : 在类内可以互相访问,在类外不能访问
2.公有 : 在类内或者类外都可以访问
类中成员:
1.成员属性
2.成员方法
绑定方法:
1.绑定到对象 : 当对象去调用类中成员方法时,系统会默认把该对象当成参数传递给该方法
2.绑定到类 : 当对象或者类去调用类中成员方法时,系统会默认把该类当成参数传递给该方法
使用方式:
对象.成员属性
对象.成员方法
"""
class MyCar():
# 公有属性
logo = "布加迪威龙"
# 私有属性, 前面加两个下划线
__price = "2000万"
# 公有方法
def run(self): # 必须要写上一个形参。调用时自动传参(强制操作)
print("百公里油耗300L,logo={} , price={}".format(self.logo, self.__price))
# 私有方法
def __info(self):
print("车主信息保密,据说是某个房地产大佬的儿子")
# 实例化对象(类的实例化)
obj = MyCar()
# (1)实例化的对象访问成员属性和方法
# 公有
print(obj.logo)
obj.run()
# 私有 (私有成员无法在类外访问,类内可以)
# obj.__price # error
# obj.run()
# obj.__info() # error
#(2)实例化的对象动态添加公有成员属性
obj.color = "黄色"
obj.logo = "五菱宏光"
print(obj.color)
print(obj.logo)
# __dict__ 获取类对象的内部成员
print(obj.__dict__)
print(MyCar.__dict__)
#(3)实例化的对象动态添加公有成员方法
# 1.无参方法 (类外定义的方法,不会强制传参)
def dahuangfeng():
print("请加我大黄蜂")
obj.dahuangfeng = dahuangfeng
obj.dahuangfeng()
# 2.有参方法
# 基本版
def qingtianzhu(name):
print("请叫我一柱擎天么,{}".format(name))
obj.qingtianzhu = qingtianzhu
obj.qingtianzhu("擎天柱")
# 升级版
def qingtianzhu(obj,name):
print("请叫我一柱擎天么,{},我的颜色是{}".format(name,obj.color))
obj.qingtianzhu = qingtianzhu
obj.qingtianzhu(obj,"擎天柱")
# 究极版
"""如果要创建绑定方法,参数的顺序,self对象本身要放到第一位."""
def qingtianzhu(obj,name):
print("请叫我一柱擎天么,{},我的颜色是{}".format(name,obj.color))
import types
# 创建绑定方法,系统自动把该对象当成参数传递给方法;
# types.MethodType(方法,对象) => 绑定方法
res = types.MethodType(qingtianzhu,obj)
print(res) # <bound method qingtianzhu of <__main__.MyCar object at 0x77>>
# 自动将obj作为参数传给该方法
obj.qingtianzhu = types.MethodType(qingtianzhu,obj)
obj.qingtianzhu("擎天柱")
# 3.lambda表达式
obj.weizhentian = lambda : print("我是威震天")
obj.weizhentian()
类的操作
"""
使用方式:
类.成员属性
类.成员方法
"""
class MyCar():
# 公有成员属性
platenum = "京A7758BB"
# 私有成员属性
__earning = "月收入6000"
# 公有成员方法
def car_info():
print("牌照信息可以公开")
print("<======>")
MyCar.__money_info()
# 私有成员方法
def __money_info():
print( "收入信息保密" , MyCar.__earning )
# (1)定义的类访问公有成员属性和方法
print(MyCar.platenum)
MyCar.car_info()
# MyCar.__money_info() error
# (2)定义的类动态添加公有成员属性
MyCar.oil = "1000L"
print(MyCar.oil)
print(MyCar.__dict__)
# (3)定义的类动态添加公有成员方法
# 1.无参方法
def car_light():
print("我是造车灯的方法")
MyCar.car_light = car_light
MyCar.car_light()
# 2.有参方法
def car_engine(name):
print("我是造{}发动机的方法".format(name))
MyCar.car_engine = car_engine
MyCar.car_engine("三缸发动机")
# 3.lambda表达式
MyCar.luntai = lambda : print("我是造轮胎的方法")
MyCar.luntai()
# 对比 对象和类之间的不同
"""
1.类中的无参方法默认只能类来调用,对象无法调取
2.对象可以调用类中的成员,反过来,类不能调用对象中的成员
3.每创建一个对象都会在内存中占用一份空间,对象之间是彼此独立的;
"""
obj = MyCar()
# obj.car_info() error
MyCar.car_info()
obj.price = "10万"
print(MyCar.price)
如何在类外访问私有成员
class Plane():
# 公有成员
captian = "赵沈阳"
# 私有成员
__air_sister = "3名空姐"
# 公有绑定方法
def fly(self):
print("飞机要非要平流层,才能减少震动",self.__air_sister)
# 私有绑定方法
def __age(self):
print("空姐年龄保密")
# 公有无参方法
def fly2():
print("航天飞机飞到天空层,翱翔太空")
# 私有无参方法
def __earn():
print("机长的收入保密")
def pub_get1(self):
print(self.__air_sister)
self.__age()
def pub_get2():
print(Plane.__air_sister)
Plane.__earn()
# 实例化对象
obj = Plane()
# 方法一.访问私有成员 (不推荐)
# python私有化: 采取了改名策略 => _类名 + __air_sister
# print(obj.__air_sister) # 报错
print(obj._Plane__air_sister)
print(Plane.__dict__)
# 方法二.访问私有成员 (使用类中的公有方法,间接访问私有成员) (推荐)
obj = Plane()
obj.pub_get1()
Plane.pub_get2()
使用类对象删除相应的成员
"""
1.对象可以访问类中的公有成员,但是无权修改或者删除该类中的成员
2.对象在访问成员时,优先访问该对象自己的成员,如果没有在访问类的,类如果也没有直接报错;
"""
# 删除对象成员属性
obj.captian = "赵世超"
del obj.captian
print(obj.captian)
# 删除对象成员方法
obj.basketball = lambda : print("我的私人飞机可以在天上打篮球")
print(obj.__dict__)
obj.basketball()
del obj.basketball
print(obj.__dict__)
# obj.basketball() # error
# 删除类中成员属性
del Plane.captian
print(Plane.__dict__)
# Plane.captian # error
# print(obj.captian) # error
# 删除类中成员方法
del Plane.fly2
# Plane.fly2() # error
# 注意: 对象无法调无参方法!! 反过来,类可以调用对象的绑定方法么? 可以!!
Plane.fly(obj)
__init__ 构造方法
'''
触发时机:实例化对象,初始化的时候触发
功能:为对象添加成员
参数:参数不固定,至少一个self参数
返回值:无
'''
# (1) 基本语法
class MyClass():
def __init__(self):
print("构造方法被触发 ... ")
self.color = "屎黄色"
# 实例化对象
obj = MyClass()
print(obj.__dict__)
print(obj.color)
# (2) 带有多个参数的构造方法
class MyClass():
def __init__(self,color):
self.color = color
# 实例化对象
obj1 = MyClass("狗屎绿")
print(obj1.color)
obj2 = MyClass("粉嫩红")
print(obj2.color)
# (3)类可以是一个,对象可以是多个,创造的对象彼此是独立的;
class Children():
def __init__(self,name,skin):
self.name = name
self.skin = skin
def cry(self):
print("小孩一下生久哇哇哇的哭")
def la(self):
print("小孩一下生久拉粑粑")
def __eat(self):
print("小孩一下生就要吃奶奶..")
def info(self):
print("小孩的名字:{},小孩的肤色{}".format(self.name,self.skin))
def info2(self,name,skin):
print("小孩的名字:{},小孩的肤色{}".format(name,skin))
# 实例化对象
afanda = Children("阿凡达","深蓝色")
afanda.cry()
afanda.info()
haoke = Children("绿巨人","绿色的")
haoke.la()
haoke.info()
wangbaoqiang = Children("王宝强","亮绿色")
wangbaoqiang.info()
# wangbaoqiang.__eat() error
wangbaoqiang.info2("张保张","黄色")
继承
"""
一个类除了自身所拥有的属性方法之外,还获取了另外一个类的成员属性和方法 是一种继承关系
被继承的类叫做父类(基类,超类),继承的类叫做子类(衍生类)
在python中所有类都继承object这个父类
继承: (1) 单继承 (2) 多继承
"""
单继承
class Human(object):
eye = "黑色的"
def jump(self):
print("古代人类都能上树")
def beat_animal(self):
print("古代人类都会打猎")
def __makefire(self): # 只能在本类内部调用
print("古代人类会生火")
# (1) 子父继承之后,子类可以调用父类的公有成员
class Man(Human):
pass
obj = Man()
obj.jump()
# (2) 子父继承之后,子类不能调用父类的私有成员
class Woman(Human):
def pub_func(self):
self.__makefire()
obj2 = Woman()
# obj2.__makefire() # 报错 不行
# obj2.pub_func() # 报错 不行 __makefire 方法调用失败
# (3) 子父继承之后,子类可以重写父类的同名公有方法
class Children(Human):
def beat_animal(self):
print("小孩天生只会打泡泡,不会打猎")
obj3 = Children()
obj3.beat_animal()
多继承
# (1) 基本语法
class Father():
property = "风流倜傥,才华横溢,玉树临风,才高八斗,学富五车,英姿洒窗"
def f_hobby():
print("抽烟喝酒烫头")
class Mother():
property = "倾国倾城,貌美如花,沉鱼落雁,闭月羞花,婀娜多姿,如花似玉"
def m_hobby(self):
print(self.property)
print("读书看报")
class Daughter(Father,Mother):
pass
obj = Daughter()
print(obj.property) # 存在顺序关系
obj.m_hobby()
# (2) 多继承的成员调用
class Father():
property = "风流倜傥,才华横溢,玉树临风,才高八斗,学富五车,英姿洒窗"
def f_hobby():
print("抽烟喝酒烫头")
class Mother():
property = "倾国倾城,貌美如花,沉鱼落雁,闭月羞花,婀娜多姿,如花似玉"
def m_hobby(self):
print(self.property)
print("读书看报")
"""
(1)super本身是一个类 super()是一个对象 用于调用父类的绑定方法
(2)super() 只应用在绑定方法中,默认自动传递self对象 (前提:super所在作用域存在self)
(3)super用途: 解决复杂的多继承调用顺序
"""
class Son(Father,Mother):
property = "打游戏,吃小零食"
def m_hobby(self):
print("son中m_hobby方法")
# 用类调用成员
def skill1(self):
Father.f_hobby()
print(Mother.property)
# 用对象调用成员
"""self按照顺序找: 对象本身 => 类 => 父类 对应的成员 """
def skill2(self):
print(self.property)
self.m_hobby()
# 用super调用成员
"""super()只调用父类的相关成员,顺带传递对象参数。不调用自己的"""
def skill3(self):
print(super()) # <super: <class 'Son'>, <Son object>>
print(super().property)
super().m_hobby()
obj2 = Son()
# obj2.skill1()
obj2.property = "喜欢看lol,dnf,wow,跑跑卡丁车,ddo,霸王大陆,澄海3"
# obj2.skill2()
obj2.skill3()
菱形继承 (钻石继承)
class Human():
pty = 1
def feelT(self):
print("古代人类,天热了,光腚1")
print(self.pty) # 4 3 2 1
print("古代人类,天冷了,穿树衣2")
class Man(Human):
# pty = 2
def feelT(self):
print("男人,天热了,光膀子3")
print(super(),"<==2==>") # <super: <class 'Man'>, <Children object>>
super().feelT()
print("男人,天冷了,光腚4")
class Woman(Human):
# pty = 3
def feelT(self):
print("女人,天热了,脱毛5")
print(super(),"<==3==>") # <super: <class 'Woman'>, <Children object>>
super().feelT()
print("女人,天冷了,穿貂6")
class Children(Man,Woman):
# pty = 4
def feelT(self):
print("小孩,天热了,光腚7")
print(super(),"<==1==>") # <super: <class 'Children'>, <Children object>>
super().feelT() # 将super() 对象传给feelT() 方法
print("小孩,天冷了,多喝热水8")
# ### super的深层理解
obj = Children()
obj.feelT()
# 73512648
"""
# 菱形继承 查找方法解析原则:super() 调用时查找顺序
# mro: 方法解析顺序 (c3算法计算的)
# 语法: 类.mro() => 列表
m :method
r :resolution
o :order
super 会自动根据mro列表返回出来的顺序关系,依次调用
super作用:专门用于解决复杂的多继承调用顺序关系;依照mro返回的列表顺序,依次调用;
super调用的顺序:会按照c3算法的广度优先原则进行调用
super传参:会默认在调用方法时,传递该对象参数;
"""
lst = Children.mro()
print(lst)
"""
[
<class '__main__.Children'>,
<class '__main__.Man'>,
<class '__main__.Woman'>,
<class '__main__.Human'>,
<class 'object'>
]
"""
内置函数 issubclass
与isinstance
issubclass
判断类的子父关系(应用在类与类之间)
class MyClass():
pass
"""只要在一条继承链上满足关系即可"""
res = issubclass(Children,Man)
res = issubclass(Children,Human)
res = issubclass(Children,MyClass) # False
# 如果元组当中有一个父类满足,即返回真
res = issubclass(Children, (Man,Human,MyClass) )
print(res) # True
isinstance
判断对象的类型 (应用在类与对象之间)
"""只要在一条继承链上满足关系即可"""
res = isinstance(obj,Children) # True
res = isinstance(obj,Human) # True
res = isinstance(obj,MyClass) # False
# 如果元组当中有一个类满足,即返回真
res = isinstance(obj, (Man,Human,MyClass) )
print(res) # True
多态
不同的子类对象,调用相同的父类方法,产生不同的执行结果文章来源:https://www.toymoban.com/news/detail-431938.html
"""继承 重写 """
class Soldier():
def attack(self):
pass
def back(self):
pass
# 陆军
class Army(Soldier):
def attack(self):
print("[陆军]开坦克装甲部队,开大炮轰炸敌方根据地,拼刺刀,手撕鬼子")
def back(self):
print("[陆军]为了一条性命,夜行八百,日行一千,回家")
# 海军
class Navy(Soldier):
def attack(self):
print("[海军]开航空母舰,扔鱼叉,撒网捆住敌人,收网")
def back(self):
print("[海军]直接跳水,下海喂鱼,原地爆炸")
# 空军
class AirForce(Soldier):
def attack(self):
print("[空军]空对地投放原子弹,空对空发射巡航导弹")
def back(self):
print("[空军]直接跳机,落地成盒")
# 创建士兵
obj1 = Army()
obj2 = Navy()
obj3 = AirForce()
#
lst = [obj1,obj2,obj3]
# lst = [Army(),Navy(),AirForce()]
strvar = """
将军请下令:
1.全体出击
2.全体撤退
3.海军出击,其他兵种撤退
"""
num = input(strvar)
for i in lst:
# print(i)
if num == "1":
i.attack() # 方法名相同,但是结果不一样
elif num == "2":
i.back()
elif num == "3":
if isinstance(i,Navy):
i.attack()
else:
i.back()
else:
print("风太大,小弟听不见")
break
python对成员的保护分为两个等级
- 私有的: private
在本类内部可以访问,类的外部不可以访问.(python中 属性或者方法前面加上两个下划线__
) - 公有的: public
在本类的内部和外部都可以访问.
# 私有成员的改名策略 [_类名__成员名]
# 对象的相关操作
(1)实例化的对象访问公有成员属性和方法
(2)实例化的对象动态添加公有成员属性和方法
(3)实例化的对象删除公有成员属性和方法
# 类的相关操作
(1)定义的类访问公有成员属性和方法
(2)定义的类动态添加公有成员属性和方法
(3)定义的类删除公有成员属性和方法
普通方法: 没有任何参数传递,只能类调用
绑定方法: 把默认传参的方法叫做绑定方法,绑定到对象(默认传对象),绑定到类(默认传类)
非绑定方法:静态方法(无需传任何参数,对象和类都能调用)
私有的:只能载类或者对象的结构中访问
公有的:可以载任何位置访问
受保护:可以载当前类或者对象 和子类或者子类对象中访问
类内 子类中 类外部
公有的: √ √ √
私有的: √ X X
受保护: √ √ X (python语言不支持)
魔术方法(特定时机自动触发)
__init__ 魔术方法(构造方法)
'''
触发时机:实例化对象,初始化的时候触发
功能:为对象添加成员
参数:参数不固定,至少一个self参数
返回值:无
'''
__new__ 魔术方法
'''
触发时机:实例化类生成对象的时候触发(触发时机在__init__之前)
功能:控制对象的创建过程
参数:至少一个cls接受当前的类,其他根据情况决定
返回值:通常返回对象或None
'''
# (1) 基本使用
class MyClass2():
a = 100
obj2 = MyClass2()
# print(obj2)
class MyClass1():
def __new__(cls):
print(cls) # <class '__mian__.MyClass1'>
# 1.返回本类对象
"""类.成员方法(类)"""
return object.__new__(cls)
# 2.返回其他类的对象
# return obj2
# 3.不返回对象,None
# return None
obj = MyClass1()
# print(obj.a)
print(obj)
# (2) __new__ 触发时机要快于 __init__
"""
# 先创建对象,然后初始化对象
__new__ 创建对象
__init__ 初始化对象
"""
class MyClass():
def __new__(cls):
print(1)
return object.__new__(cls)
def __init__(self):
print(2)
obj = MyClass() # 1 2
# (3) __new__的参数要和__init__参数一一对应
class Boat():
def __new__(cls,name): # 不加name参数会报错
return object.__new__(cls)
def __init__(self,name):
self.name = name
obj = Boat("万里阳光号")
print(obj.name)
# 使用收集参数进行改造 ***
class Boat():
# *args,**kwargs 可以收集多余的所有参数
def __new__(cls,*args,**kwargs):
return object.__new__(cls)
def __init__(self,name,type):
self.name = name
self.type = type
obj = Boat("万里阳光号","破木头做的")
print(obj.name , obj.type)
# (4) __new__和__init__之间的注意点
"""
如果 __new__ 没有返回对象或者返回的是其他类的对象,不会调用构造方法.
只有在返回自己本类对象的时候,才会调用 __iniy__ 构造方法.
"""
class Children():
def __new__(cls,*args,**kwargs):
return obj2
# pass # 需要return cls
def __init__(self,name,skin):
print("构造方法被触发 ... ")
# self.name = name
# self.skin = skin
obj = Children("灭霸","紫薯")
# 没有返回对象,默认是None,无法在None关键字上加name属性
# print(obj.name) error
# print(obj.skin) error
单例模式
同一个类,无论实例化多少次,都有且只有一个对象文章来源地址https://www.toymoban.com/news/detail-431938.html
"""
每创建一个对象,就会在内存中多占用一份空间
为了节省空间,提升执行效率,使用单态(单例)模式
场景:只是单纯调用类中的成员,而不会额外为当前对象添加成员;
"""
class Singleton():
__obj = None
def __new__(cls):
if cls.__obj is None:
cls.__obj = object.__new__(cls)
return cls.__obj
"""
第一次,在实例化对象时触发__new__魔术方法
if cls.__obj is None 条件成立 cls.__obj = object.__new__(cls) 创建一个对象给私有成员属性__obj
return cls.__obj 用obj1接收到了对象
第二次,在实例化对象时触发__new__魔术方法 if cls.__obj is None不满足,因为已经在__obj属性中存放了一个对象
return cls.__obj
第三次,在实例化对象时触发__new__魔术方法 if cls.__obj is None不满足,因为已经在__obj属性中存放了一个对象
return cls.__obj
"""
obj1 = Singleton()
obj2 = Singleton()
obj3 = Singleton()
print(obj1,obj2,obj3)
# 完整版
class Singleton():
__obj = None
def __new__(cls,*args,**kwargs):
if cls.__obj is None:
cls.__obj = object.__new__(cls)
return cls.__obj
def __init__(self,name):
self.name = name
obj1 = Singleton("康玉康")
obj2 = Singleton("张保张")
print(obj1,obj2) # 同一个对象,指向同一个内存地址
print(obj1.name) # 张保张
print(obj2.name) # 张保张
__del__ 魔术方法(析构方法)
'''
触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量 2.所有对象被del的时候]
功能:对象使用完毕后资源回收
参数:一个self接受对象
返回值:无
'''
# (1) 基本语法
class Lion():
def __init__(self,name):
self.name = name
def __del__(self):
print("析构方法被触发 ... ")
# 触发方式一: 页面执行完毕回收所有变量
obj1 = Lion("辛巴")
# 触发方式二: 所有对象被del的时候
obj2 = obj1
obj3 = obj1
print(obj2 , obj1 ,obj3)
print("<====start===>")
del obj1
del obj2 # 对象没有引用的时候才会触发
del obj3
print("<====end===>")
# (2) 模拟文件操作
import os
class ReadFile():
# 根据文件是否存在,创建对象
def __new__(cls,filename):
if os.path.exists(filename):
return object.__new__(cls)
else:
print("抱歉,没有这个文件")
# 打开文件
def __init__(self,filename):
self.fp = open(filename,mode="r",encoding="utf-8")
# 关闭文件
def __del__(self):
self.fp.close()
# 读取文件
def readcontent(self):
return self.fp.read()
obj = ReadFile("0.py")
print(obj.readcontent())
__str__ 魔术方法
'''
触发时机: 使用print(对象)或者str(对象)的时候触发
功能: 查看对象
参数: 一个self接受当前对象
返回值: 必须返回字符串类型
'''
class Cat():
gift = "抓老鼠"
def __init__(self,name):
self.name = name
def cat_gift(self):
return "小猫叫{},小猫会{}".format(self.name,self.gift)
def __str__(self):
return self.cat_gift()
__repr__ = __str__
tom = Cat("汤姆")
# 触发时机1 : print(对象)
# print(tom)
# 触发时机2 : str(对象)
res = str(tom)
print(res)
print("<==================>")
res = repr(tom)
print(res , type(res))
print("<==================>")
__repr__ 魔术方法
'''
触发时机: 使用repr(对象)的时候触发
功能: 查看对象,与魔术方法__str__相似
参数: 一个self接受当前对象
返回值: 必须返回字符串类型
'''
class Mouse():
gift = "偷油吃"
def __init__(self,name):
self.name = name
def mouse_gift(self):
return "老鼠叫{},老鼠会{}".format(self.name,self.gift)
def __repr__(self):
return self.mouse_gift()
# 系统底层默认把__repr__方法赋值给__str__方法,所以通过print或者str强转可以触发;
# __str__ = __repr__
jerry = Mouse("杰瑞")
# res = repr(jerry)
# print(res)
# 可以触发
# print(jerry)
res = str(jerry)
print(res)
__call__ 魔术方法
'''
触发时机:把对象当作函数调用的时候自动触发
功能: 模拟函数化操作
参数: 参数不固定,至少一个self参数
返回值: 看需求
'''
# (1) 基本语法
class MyClass():
def __call__(self):
print("__call__魔术方法被触发 ... ")
obj = MyClass()
obj() # 如果没写 __call__魔术方法 则报错
# (2) 利用__call__魔术方法做统一调用
class Wash():
def __call__(self,something):
print("我要洗{}".format(something))
self.step1(something)
self.step2()
self.step3()
return "洗完了"
def step1(self,something):
print("放水,把{}扔进去".format(something))
def step2(self):
print("倒洗衣粉,洗衣液,蓝月亮,金纺,立白 ... ")
def step3(self):
print("洗一洗,晾干,穿上")
obj = Wash()
# obj.step1()
# obj.step2()
# obj.step3()
res = obj("袜子")
print(res)
# (3) 模拟整型强转操作
import math
class MyInt():
def __call__(self,num):
if isinstance(num,bool):
if num == False:
return 0
else:
return 1
elif isinstance(num,int):
return num
elif isinstance(num,float):
# 方法一
# a,b = str(num).split(".")
# return eval(a)
# 方法二
"""
if num >= 0:
return math.floor(num)
else :
return math.ceil(num)
"""
# 简写
return math.floor(num) if num >= 0 else math.ceil(num)
elif isinstance(num,str):
if (num[0] == "+" or num[0] == "-") and num[1:].isdecimal():
# 获取当前字符串的正负值
if num[0] == "+":
sign = 1
elif num[0] == "-":
sign = -1
# 截取符号后面的字符串传递
return self.calc(num[1:],sign)
elif num.isdecimal():
return self.calc(num)
else:
return "这个算不了兄弟~"
# 计算最后的数值
def calc(self,num,sign=1):
# 去掉前面的"0"字符串
num = num.lstrip("0")
# print(num , type(num) , "<==============>")
if num == "":
return 0
return eval(num) * sign
myint = MyInt()
res = myint(-5.67)
print(res , type(res))
res = myint("-000000000000055555")
print(res , type(res))
res = myint("asdfasdfasdfasdf")
print(res , type(res))
# print(myint("+0000000000000"))
# bool int float 纯数字字符串
"""
print( int("00000000000001223") ) # 1223
print( int("-00000000000001223") ) # -1223
print( int("+00000000000001223") ) # 1223
print( int("+0000000000000") ) # 0
"""
# print( int("asdfasdfasdfasdf") ) # 报错
# print( eval("00000000000001223") ) # 报错
__bool__ 魔术方法
'''
触发时机:使用bool(对象)的时候自动触发
功能:强转对象
参数:一个self接受当前对象
返回值:必须是布尔类型
'''
'''
类似的还有如下等等(了解):
__complex__(self) 被complex强转对象时调用
__int__(self) 被int强转对象时调用
__float__(self) 被float强转对象时调用
...
...
'''
class MyClass():
def __bool__(self):
return True # 返回的不是bool 类型会报错
obj = MyClass()
print(bool(obj))
__add__ 魔术方法 (与之相关的__radd__ 反向加法)
'''
触发时机:使用对象进行运算相加的时候自动触发
功能:对象运算
参数:二个对象参数
返回值:运算后的值
'''
'''
类似的还有如下等等(了解):
__sub__(self, other) 定义减法的行为:-
__mul__(self, other) 定义乘法的行为:
__truediv__(self, other) 定义真除法的行为:/
...
...
'''
class MyClass():
def __init__(self,num):
self.num = num
# 当对象在 + 号的左侧时,自动触发
def __add__(self,other):
# print(self) # 对象
# print(other) # + 号右边的数据
return self.num * 3 + other
# 当对象在 + 号的右侧时,自动触发
def __radd__(self,other):
# print(self) # 对象
# print(other) # 7 + 号左边的数据
return self.num * 5 + other
# add的触发方式
a = MyClass(3)
res = a + 1
print(res) # 10
# radd的触发方式
b = MyClass(5)
res = 7 + b
print(res) # 32
# 对象 + 对象
res = a + b
print(res) # 34
"""
a+b 触发的是add魔术方法 self 接受的是a other 接受的是b
return a.num + b => return 9 + b
res = 9 + b 触发的是radd魔术方法 self 接受的是b other 接受的是9
return b.num * 5 + 9 => 5 * 5 + 9 => 34
"""
__len__ 魔术方法
'''
触发时机:使用len(对象)的时候自动触发
功能:用于检测对象中或者类中某个内容的个数
参数:一个self接受当前对象
返回值:必须返回整型
'''
'''
类似的还有如下等等(了解):
__iter__(self) 定义迭代容器中的元素的行为
__reversed__(self) 定义当被 reversed() 调用时的行为
__contains__(self, item) 定义当使用成员测试运算符(in 或 not in)时的行为
...
...
'''
# len(对象) => 类中的所有自定义成员
class MyClass():
pty1 = 1
pty2 = 2
__pty3 = 3
def func1():
pass
def func2():
pass
def __func3():
pass
def __len__(self):
# 以__开头并且以__结尾的成员过滤掉;
return len( [ i for i in MyClass.__dict__ if not ( i.startswith("__") and i.endswith("__") ) ] )
obj = MyClass()
print(len(obj))
魔术属性
class Man():
pass
class Woman():
pass
class Sasuke(Man,Woman):
"""
描述: 佐助这个的天生属性,技能
成员属性: __eye skin
成员方法: skylight __moonread
"""
__eye = "血轮眼->万花筒->轮回眼"
skin = "白色"
def skylight(self , myfunc):
print("使用天照,一团黑色的火焰 ... 恐怖如斯")
res = myfunc.__name__
print(res , type(res) )
def __moonread(self):
print("使用月读,让敌人拉入到幻术空间,被施法者掌握")
obj = Sasuke()
__dict__ 获取对象或类的内部成员结构
dic = Sasuke.__dict__ # <class 'mappingproxy'> 类型
dic = obj.__dict__ # <class 'dict'>
print(dic)
__doc__ 获取对象或类的内部文档
print(Sasuke.__doc__)
print(obj.__doc__)
__name__ 获取类名函数名
def func343434():
print("佩恩出场时,使用一手地爆天星,技惊四座,点燃所有观众")
obj.skylight(func343434) # func343434
__class__ 获取当前对象所属的类
print(obj.__class__) # <class '__main__.Sasuke'>
__bases__ 获取一个类直接继承的所有父类,返回元组
print(Sasuke.__bases__) # (<class Man>, <Woman>)
到了这里,关于【python基础语法十】面向对象的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!