面向对象2 (元类、反射)

一、成员修饰符
公有成员 self.name
私有成员 self.__age
1.python中的public --->无前导and尾随下划线
2.python中的protect --->仅一个前导下划线
3.python中的private --->最少两个前导和最多一个尾随下划线

二、特殊成员
class Foo:
def __init__(self, n, a): # 类()自动执行
self.name = n
self.age = a
def __call__(self, *args, **kwargs): # 对象() 类()()自动执行
print('call')
def __int__(self): # int(对象)
return 13
def __str__(self): # str(对象)
return '%s-%s' % (self.name, self.age)

def __add__(self, other): # obj1 + obj2
return '想要返回的对象'
def __del__(self):
print('析构方法') # 对象被销毁()时,自动执行
def __dict__(self): # 将对象中封装的所有内容通过字典的形式返回
pass
def __getitem__(self, item):pass # ls[0] ls[1:4:2]
def __setitem__(self, key, value):pass # ls[0] = 100
def __delitem__(self, key):pass # del ls[0]
def __iter__(self):pass # 如果类中有__iter__方法,对象为可迭代对象,对象.__iter__()的返回值为迭代器

obj = Foo('kay', 30)
obj() # 调用__call__() 'call'
int(obj) # 调用__int__() 13
print(obj) # 调用__str__() print(str(obj))
str(obj) # 调用__str__()
obj2 = Foo('ang', 29)
r = obj + obj2 # 自动调用第一个对象的__add__方法,并且将第二个对象当作参数传递进入

三、metaclass,类的祖宗,元类
a. Python中一切事物都是对象
b.
class Foo:pass
obj = Foo()
# obj是对象,Foo类
# Foo类也是一个对象,是type的对象
c.
类都是type类的对象, type(...)
"对象"都是类的对象 类()

Foo = type('Foo', (object,), {'func': function})
声明了一个类,类名为Foo,父类object,类中有一个成员func

python创建Foo类的实际过程

calss MyType(type):

def __init__(self, what, bases=None, dict=None):
super(MyType, self).__init__(what, bases, dict)

def __call__(self, *args, **kwargs):
obj = self.__new__(self, *args, **kwargs)

self.__init__(obj)

class Foo(object, metaclass=MyType):

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

def __new__(cls, *args, **kwargs):
return object.__new__(cls, *args, **kwargs)

obj = Foo()
# 第一阶段:解释器从上到下执行代码创建Foo类
# 第二阶段:通过Foo类创建obj对象
# 解释器解释到 calss Foo(object, metaclass=MyType): 这里时会执行MyType的__init__方法
# 解释到obj = Foo() 时,因为Foo为type的对象,所以会调用MyType的__call__方法
# MyType的__call__方法会调用对象Foo类的__new__,通过__new__方法创建Foo类的对象并返回
# 最后MyType的__call方法再调用Foo的__init__方法进行初始化


四、异常处理
try:
# 代码块
i = int(input('请输入序号:')
except Exception as e: # 出错就执行
# 上述代码块如果出错,自动执行当前块的内容
i = 1
else: # 没出错就执行
print('ok')
finally: # 无论是否出错都会执行
print('over')

主动抛出异常
try:
raise Exception('不过了') # 主动抛出异常 raise
except Exception as e:
print(e)

自定义异常
class OldError(Exception):
def __init__(self, msg):
self.message = msg

def __str__(self):
return self.message

obj = OldError('xxx') # 创建自定义异常对象obj
print(obj) # 调用对象obj的__str__方法

断言 assert
assert expression [, arguments]
assert 1 == 1, '不相等' # 条件不成立时就抛出异常信息 '不相等'
print('ok')

五、反射
反射就是通过字符串的形式,导入模块;通过字符串的形式,去模块寻找指定函数,并执行。
利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!

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

def show(self):
return '%s-%s' % (self.name, self.age)

obj = Foo('kay', 30)
b = "name"

# 通过字符串的形式操作对象中的成员
v = getattr(obj, b) # 'kay'
h = hasattr(obj, 'name') # 返回True False,判断是否有成员
setattr(obj, 'k1', 'v1') # 对obj设置 k1 = 'v1'
delattr(obj, 'name') # 删除obj的成员name

六、单例模式
单例,用于使用同一份实例(对象)
  class SingleInstance(object):
   __instance = None
   def __init__(self):
  pass

  def __new__(cls, *args, **kwargs):
  if not cls.__instance:
  cls.__instance = object.__new__(cls, *args, **kwargs)
  return cls.__instance
posted @ 2018-04-11 08:48  Ant137  阅读(112)  评论(0)    收藏  举报