# Python二十九、元编程- 最终类 ,new,单例
#利用元类生成最终类-不可被继承的类
class final(type):
def
__init__(cls,name,bases,namespace):
super(final,cls).__init__(name,bases,namespace)
print("打印父类元组:",bases,"打印final:",final)
for klass in bases:
if
isinstance(klass,final):# 判断被继承的父类是不是final的子类或元类
raise
TypeError(str(klass.__name__),"类不能被继承")
class A(object):
pass
class B(A,metaclass=final): #B继承A,并且是一个元类,内容是final
(B=final)
pass
b = B()
print(B.__bases__)
print(isinstance(B,final)) #B根据final生成元类 所以isinstanc返回true
print(isinstance(b,A)) #验证B的实例是不是属于A的类或继承A的类
class c(B):
pass
打印:
打印父类元组: (,) 打印final:
(,)
True
True
打印父类元组: (,) 打印final:
---------------------------------------------------------------------------
TypeError Traceback
(most recent call last)
in
21
print(isinstance(b,A)) #验证B的实例是不是属于A的类或继承A的类
22
---> 23 class c(B):
24 pass
in __init__(cls, name, bases, namespace)
8 for klass in bases:
9 if isinstance(klass,final):#
判断被继承的父类是不是final的子类或元类
---> 10 raise
TypeError(str(klass.__name__),"类不能被继承")
11
12
class A(object):
TypeError: ('B', '类不能被继承')
# new ,__new__ 与 __init__功能相似
# __new__()函数会在类被实例化的时候调用,new是分配空间,init只是设置参数
#继承不可变类型,例如int型,float型,init赋值无法改变不可变类型(在python3中int没有了init带参数方法),需要用new
#继承int型,实现把整数都变为正整数
class PositiveInt(int):
def __new__(cls,
value): #用init实现改变不可变
return super(PositiveInt,cls).__new__(cls,
abs(value)) #传入的值为绝对值
#继承float型,给float子类增加属性
class Float_Units(float):
def __new__(cls, value,
unit ):
obj= super(Float_Units,cls).__new__( cls, value
)
obj.unit= unit
return obj
if __name__=="__main__":
i =
PositiveInt(-3)
print(i)
speed= Float_Units( 6.5,
"km/s" )
print(speed,speed.unit)
打印:
3
6.5 km/s
# new 与 init的执行先后顺序
#!/usr/bin/env python
# coding: utf-8
#http://python-3-patterns-idioms-test.readthedocs.org/en/latest/Metaprogramming.html
from pprint import pprint
class Tag1: pass
class Tag2: pass
class Tag3:
def tag3_method(self):
pass
class MetaBase(type):
def __new__(mcl, name,
bases, atts):
print('MetaBase.__new__\n')
return super(MetaBase, mcl).__new__(mcl, name,
bases, atts)
def __init__(cls, name,
bases, atts):
print('MetaBase.__init__\n')
super(MetaBase, cls).__init__(name, bases,
atts)
class MetaNewVSInit(MetaBase): #继承MetaBase
def __new__(mcl, name,
bases, atts):
# First argument is the metaclass
``MetaNewVSInit``
print('MetaNewVSInit.__new__')
#for x in (mcl, name, bases, atts): pprint(x)
#打印 Python 数据结构
print('')
# These all work because the class hasn't been
created yet:
if 'foo' in atts: atts.pop('foo')
name += '_x'
bases += (Tag1,)
atts['baz'] = 42
return super(MetaNewVSInit, mcl).__new__(mcl,
name, bases, atts)
def __init__(cls, name,
bases, atts):
# First argument is the class being
initialized
print('MetaNewVSInit.__init__')
#for x in (cls, name, bases, atts):
pprint(x)
print('')
if 'bar' in atts: atts.pop('bar') # No
effect
name += '_y' # No effect
bases += (Tag2,) # No effect
atts['pi'] = 3.14159 # No effect
super(MetaNewVSInit, cls).__init__(name, bases,
atts)
# These do work because they operate on the
class object:
cls.__name__ += '_z'
cls.__bases__ += (Tag3,)
cls.e = 2.718
class Test(metaclass = MetaNewVSInit):
#用MetaNewVSInit创建元类
def
__init__(self):
print('Test.__init__')
def foo(self):
print('foo still here')
def bar(self):
print('bar still here')
t = Test()
print("-----------------------------------------------------------------")
print('class name: ' + Test.__name__)
print('base classes: ', [c.__name__ for c in
Test.__bases__])
print([m for m in dir(t) if not m.startswith("__")])
t.bar()
print(t.e)
打印:
MetaNewVSInit.__new__
MetaBase.__new__
MetaNewVSInit.__init__
MetaBase.__init__
Test.__init__
-----------------------------------------------------------------
class name: Test_x_z
base classes: ['Tag1', 'Tag3']
['bar', 'baz', 'e', 'tag3_method']
bar still here
2.718
# 单例模式 永远返回同一个实例
class Singleton(object):
def __new__(cls):
if not hasattr(cls,"instance"):
cls.instance = super(Singleton,cls).__new__(cls)
return cls.instance
a = Singleton()
b = Singleton()
print(a)
print(b)
print(id(a))
print(id(b))
print(a==b)
打印:
<__main__.Singleton object at 0x00000000052DE860>
<__main__.Singleton object at 0x00000000052DE860>
86894688
86894688
True
class Sing(object):
sing = None
def __new__(cls):
if (sing == None):
sing =
Sing()
return sing
aa = Singleton()
bb = Singleton()
print(aa)
print(bb)
print(id(aa))
print(id(bb))
print(aa==bb)
打印:
<__main__.Singleton object at 0x00000000052DE860>
<__main__.Singleton object at 0x00000000052DE860>
86894688
86894688
True
class S(object):
s = "2"
s1 = "3"
x = S();
y = S()
x.s="111"
print(y.s)
print(x.s)
S.s1 =333
print(x.s1)
print(y.s1)
打印:
2
111
333
333