python-study-24

总结

内置函数
isinstance
issubclass

反射 字符串
hasattr
getattr
setattr
delattr

自定义内置方法类定制类的功能
__str__
__del__

自定义元类 控制
mymeta(type)

类产生过程
__init__   加判断

类调用过程
__call__
__new__
__init__
return
View Code

复习

上节课复习:
    1、封装
        class Foo:
            __n=111 #_Foo__n
            def __init__(self,x):
                self.__x=x #self._Foo__x

            def func(self):
                self.__x #self._Foo__x
                Foo.__n #Foo._Foo__n

        obj=Foo()
        obj.__x
        Foo.__n

        Foo.__m=111
        obj,__y=22


        class Foo:
            __x=111 #_Foo__x

        class Bar(Foo):
            __x=222 #_Bar__x

    2、property
        可以将类内的函数伪装成一个数据属性去访问

        class Foo:
            def __init__(self,x):
                self.__x=x

            #新的写法
            @property
            def x(self):
                return self.__x

            @x.setter
            def x(self,val)
                self.__x=val

            @x.deleter
            def x(self):
                del self.__x


            # 古老的写法
            def get_x(self):
                pass

            def set_x(self,val):
                pass

            def del_x(self):
                pass

            x=property(get_x,set_x,del_x)
        obj=Foo(10)
        obj.x
        obj.x=1
        del obj.x


    3、绑定方法与非绑定方法
        @classmethod

        @staticmethod



今日内容:
    1、反射
        hasattr
        setattr
        getattr
        delattr

    2、内置的方法
        __str__
        __del__

    3、元类(*****)
        用于实例化产生类的类称之为元类
        __call__
        __new__

        单例模式
View Code

内置函数

# class Foo:
#     pass
#
# obj=Foo()
#
# print(isinstance(obj,Foo))

# 在python3中统一类与类型的概念
# d={'x':1} #d=dict({'x':1} #)

# print(type(d) is dict)
# print(isinstance(d,dict))

# issubclass()


class Parent:
    pass

class Sub(Parent):
    pass

print(issubclass(Sub,Parent))
print(issubclass(Parent,object))
View Code

反射

'''
1、什么是反射
    通过字符串来操作类或者对象的属性

2、如何用
    hasattr
    getattr
    setattr
    delattr


'''

class People:
    country='China'
    def __init__(self,name):
        self.name=name

    def eat(self):
        print('%s is eating' %self.name)

peo1=People('egon')

# print(hasattr(peo1,'name'))
# print(hasattr(peo1,'eat')) #peo1.eat

# print(getattr(peo1,'eat')) #peo1.eat
# print(getattr(peo1,'country',None))

# setattr(peo1,'age',18) #peo1.age=18
# print(peo1.age)

# print(peo1.__dict__)
# delattr(peo1,'name') #del peo1.name
# print(peo1.__dict__)


class Ftp:
    def __init__(self,ip,port):
        self.ip=ip
        self.port=port

    def get(self):
        print('GET function')

    def put(self):
        print('PUT function')

    def run(self):
        while True:
            choice=input('>>>: ').strip()
            # print(choice,type(choice))
            # if hasattr(self,choice):
            #     method=getattr(self,choice)
            #     method()
            # else:
            #     print('输入的命令不存在')

            method=getattr(self,choice,None)
            if method is None:
                print('输入的命令不存在')
            else:
                method()

conn=Ftp('1.1.1.1',23)
conn.run()
View Code

自定义内置方法类定制类的功能

#1、__str__方法
# class People:
#     def __init__(self,name,age):
#         self.name=name
#         self.age=age
#
#     #在对象被打印时,自动触发,应该在该方法内采集与对象self有关的信息,然后拼成字符串返回
#     def __str__(self):
#         # print('======>')
#         return '<name:%s age:%s>' %(self.name,self.age)
# obj=People('egon',18)
# obj1=People('alex',18)
# print(obj)  #obj.__str__()
# print(obj)  #obj.__str__()
# print(obj)  #obj.__str__()
# print(obj1)  #obj1.__str__()


# d={'x':1} #d=dict({'x':1})
# print(d)


#1、__del__析构方法
# __del__会在对象被删除之前自动触发
class People:
    def __init__(self,name,age):
        self.name=name
        self.age=age
        self.f=open('a.txt','rt',encoding='utf-8')

    def __del__(self):
        # print('run=-====>')
        # 做回收系统资源相关的事情
        self.f.close()

obj=People('egon',18)

print('')
View Code

元类

'''
1、什么是元类
    在python中一切皆对象,那么我们用class关键字定义的类本身也是一个对象
    负责产生该对象的类称之为元类,即元类可以简称为类的类

    class Foo: # Foo=元类()
        pass
2、为何要用元类
    元类是负责产生类的,所以我们学习元类或者自定义元类的目的
    是为了控制类的产生过程,还可以控制对象的产生过程

3、如何用元类

'''
#1、储备知识:内置函数exec的用法
# cmd="""
# x=1
# def func(self):
#     pass
# """
# class_dic={}
# exec(cmd,{},class_dic)
#
# print(class_dic)

#2、创建类的方法有两种
# 大前提:如果说类也是对象的化,那么用class关键字的去创建类的过程也是一个实例化的过程
# 该实例化的目的是为了得到一个类,调用的是元类
#2.1 方式一:用的默认的元类type
# class People: #People=type(...)
#     country='China'
#     def __init__(self,name,age):
#         self.name=name
#         self.age=age
#
#     def eat(self):
#         print('%s is eating' %self.name)

# print(type(People))

#2.1.1 创建类的3个要素:类名,基类,类的名称空间
class_name='People'
class_bases=(object,)
class_dic={}
class_body="""
country='China'
def __init__(self,name,age):
    self.name=name
    self.age=age

def eat(self):
    print('%s is eating' %self.name)
"""
exec(class_body,{},class_dic)

# 准备好创建类的三要素
# print(class_name)
# print(class_bases)
# print(class_dic)

# People=type(类名,基类,类的名称空间)
# People1=type(class_name,class_bases,class_dic)
# print(People1)
# obj1=People1('egon',18)
# print(People)
# obj=People('egon',18)
#
# obj1.eat()
# obj.eat()

'''
#2.2 方式二:用的自定义的元类
class Mymeta(type): #只有继承了type类才能称之为一个元类,否则就是一个普通的自定义类
    def __init__(self,class_name,class_bases,class_dic):
        print(self) #现在是People
        print(class_name)
        print(class_bases)
        print(class_dic)
        super(Mymeta,self).__init__(class_name,class_bases,class_dic) #重用父类的功能

# 分析用class自定义类的运行原理(而非元类的的运行原理):
#1、拿到一个字符串格式的类名class_name='People'
#2、拿到一个类的基类们class_bases=(obejct,)
#3、执行类体代码,拿到一个类的名称空间class_dic={...}
#4、调用People=type(class_name,class_bases,class_dic)
class People(object,metaclass=Mymeta): #People=Mymeta(类名,基类们,类的名称空间)
    country='China'
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def eat(self):
        print('%s is eating' %self.name)


# 应用:自定义元类控制类的产生过程,类的产生过程其实就是元类的调用过程

class Mymeta(type): #只有继承了type类才能称之为一个元类,否则就是一个普通的自定义类
    def __init__(self,class_name,class_bases,class_dic):
        if class_dic.get('__doc__') is None or len(class_dic.get('__doc__').strip()) == 0:
            raise TypeError('类中必须有文档注释,并且文档注释不能为空')
        if not class_name.istitle():
            raise TypeError('类名首字母必须大写')
        super(Mymeta,self).__init__(class_name,class_bases,class_dic) #重用父类的功能

class People(object,metaclass=Mymeta): #People=Mymeta('People',(object,),{....})
    """这是People类"""
    country='China'
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def eat(self):
        print('%s is eating' %self.name)
'''


#3 储备知识:__call__
# class Foo:
#     def __call__(self, *args, **kwargs):
#         print(self)
#         print(args)
#         print(kwargs)
#
#
# obj=Foo()
#
# # 要想让obj这个对象变成一个可调用的对象,需要在该对象的类中定义一个方法__call__方法
# # 该方法会在调用对象时自动触发
# obj(1,2,3,x=1,y=2)


# 4、自定义元类来控制类的调用的过程,即类的实例化过程
class Mymeta(type):

    def __call__(self, *args, **kwargs):
        # print(self) # self是People
        # print(args)
        # print(kwargs)
        # return 123

        # 1、先造出一个People的空对象
        obj=self.__new__(self)
        # 2、为该对空对象初始化独有的属性
        # print(args,kwargs)
        self.__init__(obj,*args,**kwargs)

        # 3、返回一个初始好的对象
        return obj


class People(object,metaclass=Mymeta):
    country='China'
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def eat(self):
        print('%s is eating' %self.name)

    def __new__(cls, *args, **kwargs):
        print(cls)
        # cls.__new__(cls) # 错误
        obj=super(People,cls).__new__(cls)
        return obj

# 分析:调用Pepole的目的
#1、先造出一个People的空对象
#2、为该对空对象初始化独有的属性
# obj1=People('egon1',age=18)
# obj2=People('egon2',age=18)
# print(obj1)
# print(obj2)

obj=People('egon',age=18)
print(obj.__dict__)
print(obj.name)
obj.eat()
View Code

猜你喜欢

转载自www.cnblogs.com/xujinjin18/p/9244664.html
今日推荐