面向对象进阶

2018-08-31  本文已影响0人  Snackk
class A:
    pass
class B(A):
    pass
a = A()
b = B()

反射

好处一:实现可插拔机制,先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能
好处二:动态导入模块(基于反射当前模块成员)

class BlackMedium:
    feature='Ugly'
    def __init__(self,name,addr):
        self.name=name
        self.addr=addr

    def sell_house(self):
        print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' %self.name)
    def rent_house(self):
        print('%s 黑中介租房子啦,傻逼才租呢' %self.name)

b1=BlackMedium('万成置地','回龙观天露园')

#检测是否含有某属性
print(hasattr(b1,'name'))
print(hasattr(b1,'sell_house'))

#获取属性
n=getattr(b1,'name')
print(n)
func=getattr(b1,'rent_house')
func()

# getattr(b1,'aaaaaaaa') #报错
print(getattr(b1,'aaaaaaaa','不存在啊'))

#设置属性
setattr(b1,'sb',True)
setattr(b1,'show_name',lambda self:self.name+'sb')
print(b1.__dict__)
print(b1.show_name(b1))

#删除属性
delattr(b1,'addr')
delattr(b1,'show_name')
delattr(b1,'show_name111')#不存在,则报错

print(b1.__dict__)
* input
    * 用户输入的如果是a,那么就打印1,如果输入的是b就打印2,如果输入的是name,就打印alex
* 文件
    * 从文件中读出的字符串,想转换成变量的名字
* 网络
    * 将网络传输的字符串转换成变量的名字
import sys
print(sys.modules['__main__'])  # 本文件的命名空间
print(sys.modules[__name__])     # 反射本文件中的变量 固定的使用这个命名空间
print(sys.modules['__main__'].a)
print(getattr(sys.modules[__name__],'a'))   #a是一个变量
obj = getattr(sys.modules[__name__],'Foo')()  #反射一个类实例化一个obj

不是需要程序员定义,本身就存在在类中的方法就是内置方法
内置的方法通常都长这样 : __名字__
名字 : 双下方法、 魔术方法、 内置方法
所有的双下方法,都不需要我们直接去调用,都有另外一种自动触发它的语法

class Foo:
    def __str__(self):      #2
        return 'Foo.str'
    def __repr__(self):     #4
        return 'Foo.repr'


class Son(Foo):
    # pass
    def __str__(self):       #1
        return 'Son.str'

    def __repr__(self):
        return 'Son.repr'    #3

s1 = Son()
print(s1)

反射总结:

反射 用字符串类型的变量名来获取变量的值
hasattr(命名空间,'变量名')
getattr(命名空间,'变量名')
    类名.静态属性  getattr(类名,'静态属性')
    类名.类方法()  getattr(类名,'类方法')()
    类名.静态方法()  getattr(类名,'静态方法')()

    对象.对象属性  getattr(对象,'对象属性')
    对象.方法()    getattr(对象,'方法')()

    模块名.方法名
    模块名.类名
    模块名.变量
    模块名.函数

    本文件反射
    import sys
    getattr(sys.modules[__name__],'所有定义在这个文件中的名字')
setattr 给命名空间的某一个名字设置一个值
delattr 删除某一个命名空间中变量对应的值
内置方法
不用调用调用这个方法就可以出发这个方法的执行
class Foo:
    def __str__(self):
        return 'abcd'
    def __repr__(self):
        return 'dcba'
obj = Foo()
__str__ :
    print(obj)
    '%s'%obj
    str(obj)
__repr__  : # 当使用会触发str方法的方式,但是Foo类内部又没有实现__str__方法的时候,都会调用__repr__
    '%r'%obj
    repr(obj)
class Foo:
   def __init__(self):                 # 初始化方法
       print('执行了init')
   def __new__(cls, *args, **kwargs):  # 构造方法
       # object.__new__(cls)
       print('执行了new')
       return object.__new__(cls)
obj = Foo()

new 是小人捏出来了
init 给小人穿衣服

设计模式 常用的23种
java里来的
python
推崇设计模式 java开发
贬低设计模式 纯python开发

单例模式
一个类 只有一个实例的时候 单例模式

class Foo:
    __instance = None
    def __init__(self,name,age):                 # 初始化方法
        self.name = name
        self.age = age
        self.lst = [name]
    def __new__(cls, *args, **kwargs):  # 构造方法
        if cls.__instance is None:
            cls.__instance = object.__new__(cls)
        return cls.__instance

obj1 = Foo('alex',20)
obj2 = Foo('egon',22)
print(obj1.lst,obj2.lst)
class Foo:
    def __init__(self,name,age):
        self.name = name
        self.age = age
        self.file = open('file',mode = 'w')
    def write(self):
        self.file.write('sjahgkldhgl')
    def __del__(self):    # 析构方法 : 在删除这个类创建的对象的时候会先触发这个方法,再删除对象
        # 做一些清理工作,比如说关闭文件,关闭网络的链接,数据库的链接
        self.file.close()
        print('执行del了')

f = Foo('alex',20)
print(f)
class Foo:
    def __len__(self):
        return 1
obj = Foo()
print(len(obj))

hash算法
1.对于相同的值在一次程序的运行中是不会变化的
2.对于不同的值在一次程序的运行中总是不同的

上一篇 下一篇

猜你喜欢

热点阅读