Python社区  »  Python

Python(十三)面向对象高级

Lonelyroots • 2 周前 • 16 次点击  
'''
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
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/121305
 
16 次点击  
分享到微博