我的python之路【第七章】面向对象编程高级

 

什么是类和对象

class Garen:
    camp='Demacia'
    def __init__(self,nickname,aggresivity,life_value):
        self.nickname=nickname
        self.aggresivity=aggresivity
        self.life_value=life_value

    def attack(self,enemy):
        print('is attacting')

#类的第一个功能:实例化
g1=Garen('草丛伦',82,100)
#类的的第二个功能:属性引用,包含数据属性和函数属性
g1.attack(2222)
#对于一个实例来说,只有一个功能:属性引用,实例本身只拥有数据属性
print(g1.nickname)
print(g1.aggresivity)
print(g1.life_value)

接口与归一化设计

#接口的概念,父类只写名字,不写实现
class ALLFile:  #接口类
    def read(self): #接口函数
        pass
    def write(self):
        pass
class Text(ALLFile):    #子类继承父类
    def read(self):
        print('text read')
    def write(self):
        print('text write')
class Sata(ALLFile):    #子类继承父类
    def read(self):
        print('sata read')
    def write(self):
        print('sata write')
t=Text()
s=Sata()
t.read()
t.write()
s.read()
s.write()

抽象类

import abc
class ALLFile(metaclass=abc.ABCMeta):  #抽象类
    @abc.abstractmethod      #加这个装饰器的必须在子类中实现
    def read(self): #
        pass
    @abc.abstractmethod     #加这个装饰器的必须在子类中实现
    def write(self):
        pass
    def test(self):#可以不被实现
        print('22222222')
class Text(ALLFile):    #子类中必须实现父类中规定的两个方法
    def read(self):pass
    def write(self):pass
t1=Text()
t1.test()
# 抽象类不能被实例化,
# a=ALLFile()

反射

class Foo:
    def __init__(self,name):
        self.name=name
    def func(self):
        print('func')

f = Foo('egon')
print(Foo.__dict__)
print(f.__dict__)
#hasattr判断类中是否有这个func的名字
print(hasattr(Foo,'func'))

#判断实例中是否有x这个属性
print(hasattr(f,'x'))
f.x=1
#根据字符串,调用实例中的属性
print(getattr(f,'x'))
#常用组合
if hasattr(f,'func'):
    getattr(f,'func')()
#调用,如果没有,返回None
print(getattr(f,'y',None))
#设置一个属性
#f.y=1
setattr(f,'y',1)

 

 

属性方法:

class A:
    def __init__(self,name):
        self.__name=name
    @property   #将这个类中的方法,变成一个类中的属性,可以通过.name调用
    def name(self):
        return self.__name      #当调用.name时返回的是__self.name
    @name.setter    #赋值操作调用,当为.name赋值时调用
    def name(self,value):
       # print('------')
        if not isinstance(value,str):   #判断赋值的是不是字符
           raise TypeError('%s must be str'%value)#抛出异常
        self.__name=value
    @name.deleter   #删除.name属性时调用
    def name(self):
        print('=====')
        del self.__name
a=A('ennn')
print(a.name)
a.name='ssa'
print(a.name)
del a.name

继承

class A:    #默认继承object
    pass
class B(A):#继承A
    pass
#打印继承的父类
print(B.__bases__)  #继承了
print(A.__bases__)  #

#新式的类
class Animal:

    start='earth'
    def __init__(self,name,age,gender):
        self.name=name
        self.age=age
        self.gender=gender
    def run(self):
        print('running')
    def talk(self):
        print('talking')
class People(Animal):
    pass
    def piao(self):
        print('大保健')
class Pig(Animal):
    pass

p1=People('alex',50,'F')
pig1=Pig('贺磊',250,'22')
print(p1.start)
p1.run()
#继承可以重用代码
class Hero:
    def __init__(self,nickname,aggresivity,life_value):
        self.nickname=nickname
        self.aggresivity=aggresivity
        self.life_value=life_value

    def attack(self,enemy):
        print('is attacting',enemy.nickname)
        enemy.life_value-=self.aggresivity
class Garen(Hero):
    camp='Demacia'

class Riven(Hero):
    camp='Noxus'

子类继承父类的方法:super()

class People(object):
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
class Teacher(People):
    def __init__(self,name,age,sex,level):
        #People.__init__(name,age,sex)  #需要知道父类的名字~
        super().__init__(name,age,sex)  #推荐用法
        self.level=level
t1=Teacher('alex',22,'m','高级')
print(t1.name)

静态方法

@staticmethod
静态方法不属于实例,也不属于类
与类只是名义上的归属关系
@classmethod
类方法
只能访问类变量,不能访问实例变量
import time
class Date:
    def __init__(self,year,month,day):
        self.year=year
        self.month=month
        self.day=day
    @staticmethod   #静态方法
    def now():
        t=time.localtime()
        return Date(t.tm_year,t.tm_mon,t.tm_mday)
    '''打印:
            <__main__.Date object at 0x0000022298A754A8>'''
    @classmethod #改成类方法
    def class_now(cls):
        t=time.localtime()
        return cls(t.tm_year,t.tm_mon,t.tm_mday) #哪个类来调用,即用哪个类cls来实例化
    '''
    输出结果:
    year:2017 month:3 day:3
    '''
class EuroDate(Date):
    def __str__(self):
        return 'year:%s month:%s day:%s' %(self.year,self.month,self.day)

e=EuroDate.now()
print(e) #我们的意图是想触发EuroDate.__str__,此时e就是由EuroDate产生的,所以会如我们所愿
print(EuroDate.class_now())
print(Date.now())

面向对象高级使用

class Foo:
    def __init__(self,name):
        self.name=name

    def __getitem__(self, item):
        print(self.__dict__[item])

    def __setitem__(self, key, value):
        self.__dict__[key]=value
    def __delitem__(self, key):
        print('del obj[key]时,我执行')
        self.__dict__.pop(key)
    def __delattr__(self, item):
        print('del obj.key时,我执行')
        self.__dict__.pop(item)
f=Foo('egon')
print(f['name'])
f['x']=1
print(f.__dict__)
del f.x
#del f['x']

 

创建类的方法:追本溯源

#创建两个函数
def init(self,name,age):
    self.name=name
    self.age=age
def sayhi(self):
    print('hello',self.name)
#使用type方法创建类
Test=type('Test',(object,),{'sayhi':sayhi,'__init__':init})
#生成实例
test_obj=Test('liuhao','22')
#调用实例方法
test_obj.sayhi()
'''__new__:object继承到的方法:用途是生成实例对象'''
class Foo(object):
    def __init__(self,name):
        self.name=name
        print('Foo__init__')
    #__new__:生成实例的方法
    def __new__(cls, *args, **kwargs):  #覆盖了object中的new
        '''这里负责调用实例化,事实:就是将类的内存地址复制一份,开辟一块新的内存空间,打算给实例用
            这里就是生成实例对象的内存地址,并且返回
        '''
        print('Foo __new__')
        #object.__new__(cls)        #实例化后的内存地址
        obj=object.__new__(cls)
        print('obj',dir(obj))
        print(obj)
        return obj      #返回obj这个内存空间

f=Foo('alex')
print(dir(f))
print(f)
print(f.name)

metaclass

class MyType(type):
    def __init__(self,*args,**kwargs):
        print('MyType  __init__',self,*args,**kwargs)
    def __new__(cls, *args, **kwargs):
        print('MyType __new__',cls,*args,**kwargs)
        obj=type.__new__(cls,*args,**kwargs)
        return obj
    def __call__(self, *args, **kwargs):    #在f=Foo('Alex') 时调用   self =Foo    *args = 'Alex'
        #这里传入的self 是已经执行完成MyType中__init__ 和 __new__ 的。 执行完的过程  __new__ 返回了obj = type.__new__(cls)  这个时候  self 中__new__ 其实就是 type.__new__
        print('MyType __call__',self,*args,**kwargs)
        # print(self.__new__)
        obj=self.__new__(self)      #这里执行的是object中继承的.__new__(cls)
        self.__init__(obj,*args,**kwargs)       #Foo 中的__init__已经重写
        obj.age=22
        return obj
class Foo(object,metaclass=MyType):
    def __init__(self,name):
        self.name=name
        print('Foo __init__ ')
   # print(__init__)
#下面全部注释状态下
'''
会通过MyType生成 Foo这个类:对于MyType来说也是一个对象
先执行Mype__new__()
再执行Mype__init__()
MyType __new__ <class '__main__.MyType'> Foo (<class 'object'>,) {'__init__': <function Foo.__init__ at 0x0000020EDCCF98C8>, '__qualname__': 'Foo', '__module__': '__main__'}
MyType  __init__ <class '__main__.Foo'> Foo (<class 'object'>,) {'__init__': <function Foo.__init__ at 0x0000020EDCCF98C8>, '__qualname__': 'Foo', '__module__': '__main__'}
'''
#相当于为Foo加() 默认会执行 __call__() 这里的Foo = MyType 中 __new__返回的内存地址
f=Foo('Alex')
'''
生成实例f :Foo加上()
执行MyType中的__call__()
'''
print(Foo.__module__)

 导入模块

import importlib

__import__('lib.aa')

# importlib.import_module('lib.aa')

 

posted @ 2017-03-21 14:58  saynobody  阅读(199)  评论(0编辑  收藏  举报