面向对象高级

补充内置函数:

isinstance和issubclass

class People:
    def run(self):
        print('people run')
class Student(People):
    print('student')
obj=People()
print(isinstance(obj,People))
# isinstance(对象,类)判断一个对象的类型
print(issubclass(Student,People))
# issubclass(子类,类)判断是否是子类

反射:

下述四个函数专门用来操作类与对属性的
hasattr() getattr() setattr() delattr()
通过字符串来操作类与对象的属性,这种方式被称为反射
class School:
    school='oldboy'
    def __init__(self,name,age):
        self.name=name
        self.age=age
obj=School('egon',20)
print(hasattr(obj,'school'))
print(hasattr(obj,'name'))
# hasattr(对象,Name)判断属性是否属于这个类的!!!注意Name一定要是字符串
print(getattr(obj,'school',None))
print(getattr(obj,'age',None))
# getattr(对象,Name,默认值)得到属性的值,默认值是找不到属性的时候,返回None
setattr(School,'x',1)
print(School.__dict__)#{'__module__': '__main__', 'school': 'oldboy', '__init__': <function School.__init__ at 0x000001F40F6198C8>, '__dict__': <attribute '__dict__' of 'School' objects>, '__weakref__': <attribute '__weakref__' of 'School' objects>, '__doc__': None, 'x': 1}
setattr(obj,"age",18)
print(obj.__dict__)#{'name': 'egon', 'age': 18}
# setattr(对象,属性,属性的值)打印返回的值是None
delattr(obj,'name')
print(obj.__dict__)#{'age': 18}
# delattr(对象,属性)打印返回的值是None

__str__内置

# __str__在打印的时候被触发
class People:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

    def __str__(self):
        return '''
        姓名:%s
        名字:%s
        性别:%s

        '''%(self.name,self.age,self.sex)
obj=People('egon',18,'male')
print(obj)

__del__内置

# __del__在对象被删除的条件下,自动执行
class People:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

    def __del__(self):
        print('__del__')
        del obj.name
obj=People('egon',18,'male')
# __del__结果

介绍一下exec

 

code="""
global x
x=0
y=2
"""#(字符串的形式,如果你不指定默认存为局部名称空间)
global_dic={'x':100000}#(全局名称空间)
local_dic={}#(局部名称空间)
exec(code,global_dic,local_dic)#exec(字符串,全局名称空间,局部名称空间)如果名称空间直接放一个空字典 则为空
print(global_dic)
print(local_dic)

 

 

元类:类的类就是元类
我们用class定义的类使用来产生我们自己的对象
内置元类type是用来专门产生class定义的类的
Chinese=type(...)#(类的类,元类)
class Chinese:#(类)
    country="China"

    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

    def speak(self):
        print('%s speak Chinese' %self.name)

print(Chinese)
p=Chinese('egon',18,'male')
print(type(p))#(直接打印p的到的是类型和内存地址)
print(type(Chinese))

2、用内置的元类type,来实例化得到我们的

class_name='Chinese'
class_bases=(object,)
class_body="""
country="China"
def __init__(self,name,age,sex):
    self.name=name
    self.age=age
    self.sex=sex
def speak(self):
    print('%s speak Chinese' %self.name)
"""
class_dic={}
exec(class_body,{},class_dic)

# 类的三大要素(类名,父类,局部名称空间)
# print(class_name,class_bases,class_dic)

Chinese=type(class_name,class_bases,class_dic)
print(Chinese)

p=Chinese('egon',18,'male')
print(p.name,p.age,p.sex)

3、储备知识__call__

调用对象,则会自动触发对象下的绑定方法__call__的执行,

然后将对象本身当作第一个参数传给self,将调用对象时括号内的值

传给*args与**kwargs

class Foo:
    def __init__(self):
        pass
    def __str__(self):
        return '123123'

    def __del__(self):
        pass

    def __call__(self, *args, **kwargs):
        print('__call__',args,kwargs)


obj=Foo()
print(obj)

obj(1,2,3,a=1,b=2,c=3) #

4 、自定义元类:

class Mymeta(type):
    # 来控制类Foo的创建
    def __init__(self,class_name,class_bases,class_dic): #self=Foo
        # print(class_name)
        # print(class_bases)
        # print(class_dic)
        if not class_name.istitle():
            raise TypeError('类名的首字母必须大写傻叉')

        if not class_dic.get('__doc__'):
            raise TypeError('类中必须写好文档注释,大傻叉')

        super(Mymeta,self).__init__(class_name,class_bases,class_dic)

    # 控制类Foo的调用过程,即控制实例化Foo的过程
    def __call__(self, *args, **kwargs): #self=Foo,args=(1111,) kwargs={}
        # print(self)
        # print(args)
        # print(kwargs)

        #1 造一个空对象obj
        obj=object.__new__(self)

        #2、调用Foo.__init__,将obj连同调用Foo括号内的参数一同传给__init__
        self.__init__(obj,*args,**kwargs)

        return obj



#Foo=Mymeta('Foo',(object,),class_dic)
class Foo(object,metaclass=Mymeta):
    """
    文档注释
    """
    x=1
    def __init__(self,y):
        self.y=y

    def f1(self):
        print('from f1')


obj=Foo(1111) #Foo.__call__()

print(obj)
print(obj.y)
print(obj.f1)
print(obj.x)

 单列模式

import settings

class MySQL:
    __instance=None
    def __init__(self,ip,port):
        self.ip=ip
        self.port=port

    @classmethod
    def singleton(cls):
        if not cls.__instance:
            obj=cls(settings.IP, settings.PORT)
            cls.__instance=obj
        return cls.__instance

obj1=MySQL('1.1.1.2',3306)
obj2=MySQL('1.1.1.3',3307)
obj3=MySQL('1.1.1.4',3308)

# obj4=MySQL(settings.IP,settings.PORT)
# print(obj4.ip,obj4.port)

obj4=MySQL.singleton()
obj5=MySQL.singleton()
obj6=MySQL.singleton()

print(obj4 is obj5 is obj6)

 

 

 

 

 

 


 

 

 
posted @ 2018-04-17 19:14  谎~言  阅读(94)  评论(0编辑  收藏  举报