'''
class 类名定义首字母大写
类:抽象事物
特性:手、眼睛、嘴巴 变量->属性
功能:吃饭、睡觉 函数->方法
特定的具体的对象:实例化操作
所有类都会继承object类
mro()可以查看类继承的父类
子类继承以后,可以调用父类的所有方法
'''
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self):
print("今天不睡觉,加班")
xc = Person("小陈",'27')
print(xc) # <__main__.Person object at 0x000002D494BF07B8>
xc.sleep() # 今天不睡觉,加班
print(xc.age) # 27
class Hun(Person):
pass
hx = Hun('小白','27')
hx.sleep()
print(hx.name) # 小白
'''内置函数'''
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self):
print("今天不睡觉,加班")
xc = Person("小陈",'27')
print(xc) # <__main__.Person object at 0x000002D494BF07B8>
xc.sleep() # 今天不睡觉,加班
print(xc.age) # 27
# hasattr(实例对象,'属性')两个参数,判断某属性是否存在
print(hasattr(xc,'sex')) # 属性是字符串需要带引号,判断sex是否存在,存在则返回True
# setattr(实例对象,'属性','传的值'),属性不存在添加属性,属性存在则进行修改
setattr(xc,'sex','男')
print(hasattr(xc,'sex'))
# 获取属性值
# print(getattr(xc,'ccc')) # 类似.方式调用,获取属性值,无则报错
# or
# xc.ccc
# 删除属性
delattr(xc,'sex')
print(hasattr(xc,'sex'))
'''对象关系方法'''
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self):
print("今天不睡觉,加班")
class Hunxue(Person):
pass
hn = Hunxue("小陈",28)
# 判断一个类是不是另一个类的子类
print(issubclass(Hunxue,Person)) # 前面继承后面的,则True,反之False
print(issubclass(Person,object)) # True
print(issubclass(Hunxue,(Person,object))) # hunxue类是不是继承了二者其一?两个有一个则返回True
# 判断这个实例对象是不是hunxue类所实例化得到的
print(isinstance(hn,Hunxue)) # True
# 判断前者是不是符合后者的类型
b = 1.1
print(isinstance(b,float)) # True
'''属性调用过程'''
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self):
print("今天不睡觉,加班")
class Hunxue(Person):
# 通过底层逻辑:.操作和getattr操作是当属性不存在时,调用getattr方法,所以将此方法重写,防止调用时无属性而导致报错,即自行规避报错
# 子类重写父类里的方法__getattr__,防止属性不存在,调用而导致报错
def __getattr__(self,item): # 两个参数:一个实例对象,一个属性
print("您输入的属性不存在",item)
hn = Hunxue("小陈",28)
print(dir(Hunxue)) # '__ __'的方法代表魔术方法,可以直接调用
# hn.name,getattr(hn,'name')实则在底层调用__getattr__方法(属性存在)或者调用__getattribute__方法(属性不存在),报错信息也是相同的,底层逻辑相同
print(getattr(hn,"name")) # 小陈
getattr(hn,"sss") # 您输入的属性不存在 sss
'''
魔术方法:
__new__(cls):创建实例对象,类里面创建的,self实例对象,cls表示的就是类
__init__(self):
'''
print(dir(object))
# Maomi类的父类是object
class Maomi:
def __init__(self):
print("这是在实例化时候自动调用的魔术方法")
# Maomi没写new方法之前,调用的是object类的__new__方法,这里是重写父类object里的__new__方法
# 那怎么创建实例对象?从父类当中把new方法拿来
def __new__(cls):
print("这是实例化方法,在init之前会被调用")
# 返回实例对象,需要变量接收
return super().__new__(cls) # 继承父类object里的new方法
tm = Maomi()
print(tm) # <__main__.Maomi object at 0x000001DB2A12B2B0>
'''
单例模式:
实例化一次之后,就有了一个实例对象
下一次实例化的时候,要保证只是当前的实例对象
判断实例对象是否存在。存在:使用当前的,不存在:运行创建实例对象
'''
class Maomi:
def __init__(self):
print("这是在实例化时候自动调用的魔术方法")
# Maomi没写new方法之前,调用的是object类的__new__方法,这里是重写父类object里的__new__方法
# 那怎么创建实例对象?从父类当中把new方法拿来
def __new__(cls):
print("这是实例化方法,在init之前会被调用")
if not hasattr(cls,'_istance'): # 判断类属性是否存在
# 返回实例对象,需要变量接收
# cls.istance = 在类当中定义属性,类似于age=18
cls._istance = super().__new__(cls) # 继承父类object里的new方法
return cls._istance
tm = Maomi()
jf = Maomi()
print(jf is tm) # True,单例模式返回True,地址值相同,就是同一个对象
'''
输出魔术方法:
__repr__:若没有__str__的方法,则打印__repr__方法的修改
__str__:若__repr__和__str__方法都存在,则只打印__str__方法的修改
'''
class Maomi:
def __init__(self):
print("这是在实例化时候自动调用的魔术方法")
# Maomi没写new方法之前,调用的是object类的__new__方法,这里是重写父类object里的__new__方法
# 那怎么创建实例对象?从父类当中把new方法拿来
def __new__(cls):
print("这是实例化方法,在init之前会被调用")
if not hasattr(cls,'_istance'): # 判断类属性是否存在
# 返回实例对象,需要变量接收
# cls.istance = 在类当中定义属性,类似于age=18
cls._istance = super().__new__(cls) # 继承父类object里的new方法
return cls._istance
def __repr__(self):
return "这是你的实例对象"
def __str__(self):
return 'this is your 实例对象'
tm = Maomi()
jf = Maomi()
print(jf) # 打印:这是你的实例对象
'''
协议:
列表、字符串、元组 序列类型,能够下标取值
__iter__方法
协议是需要两个或两个以上的魔术方法
'''
# 序列协议
# class Person:
# def __init__(self,*args): # 参数:元组不定长
# # 拿到传的所有元素
# self.value = args # 实例对象的变量名和后面的变量名不需要保持一致
#
# # 查看元素个数:签len协议,返回长度
# def __len__(self):
# return len(self.value)
#
# # 下标取值:签getitem协议
# def __getitem__(self,item):
# return self.value[item]
#
# def __repr__(self):
# return str(self.value)
#
# bd = Person(1,2,3,4)
# print(len(bd)) # 4
# print(bd[0]) # 1
# print(bd) # 字符串类型包含元组的数据(1, 2, 3, 4)
'''迭代器协议:__iter__方法、__next__方法'''
# li = [1,2]
# # 列表迭代底层逻辑调用的两个魔术方法,__iter__、next()
# print(li.__iter__()) # <list_iterator object at 0x000001E6381EB320>
# f = li.__iter__()
# print(next(f)) # 1
# print(next(f)) # 2
# class frange:
# def __init__(self,end = 10):
# self.start = -1
# self.end = end # 不传值,默认到10结束
#
# # 把类的实例对象成为可以迭代对象
# def __iter__(self):
# return self
#
# # 定义步长更新,即加1
# def __next__(self):
# self.start += 1
# if self.start >= self.end:
# # 主动报错
# raise StopIteration # next()迭代超上限,主动报错
# return self.start
#
# f = frange()
# for i in f:
# print(i)
'''
上下文协议:
__enter__ :程序执行之前调用
__exit__:程序结束时调用
'''
# import time
# print(time.time()) # 时间戳1970年1月1日0:0:0,到现在
#
# class Number:
# # 得到当前的时间
# def __enter__(self):
# self.start = time.time()
# return self.start
#
# # 得到结束的时间:参数:错误类型,错误的值,最终异常错误
# def __exit__(self,exc_type,exc_val,exc_tb):
# self.end = time.time()
# print("程序执行的时间是:",self.end-self.start)
#
# with Number():
# # 放需要执行的程序
# for i in range(10000000):
# pass