比Python更牛的语言有吗?看我用元类(metaclass)花式创建Python类
class ObjectCreator(object): passmy_object = ObjectCreator()print(my_object)class ObjectCreator(object):pass
class ObjectCreator(object): pass
# 由于ObjectCreator是一个对象,所以可以打印ObjectCreatorprint(ObjectCreator)
def echo(obj): print(obj)# 可以将ObjectCreator作为值参传入函数echo(ObjectCreator)
# 判断ObjectCreator是否存在new_attribute属性print(hasattr(ObjectCreator, 'new_attribute'))# 为ObjectCreator动态添加属性ObjectCreator.new_attribute = 'value'# 判断ObjectCreator是否存在new_attribute属性print(hasattr(ObjectCreator, 'new_attribute'))
# 将ObjectCreator赋给另一个变量ObjectCreatorMirror = ObjectCreatorprint(ObjectCreatorMirror.new_attribute)
print(ObjectCreatorMirror())<class '__main__.ObjectCreator'><class '__main__.ObjectCreator'>FalseTruevalue<__main__.ObjectCreator object at 0x105053780>
# 将ObjectCreator赋给另一个变量ObjectCreatorMirror = ObjectCreatorprint(ObjectCreatorMirror.new_attribute)print(ObjectCreatorMirror())def choose_class(name): if name == 'foo': class Foo(object): pass return Foo # return the class, not an instance else: class Bar(object): pass return Bar
MyClass = choose_class('foo')print(MyClass) # 函数返回一个类,而不是一个类的实例print(MyClass()) # 创建一个类实例<class '__main__.choose_class.<locals>.Foo'><__main__.choose_class.<locals>.Foo object at 0x10e905438>
# 获取函数的类型print(type(1)) # <type 'int'>print(type('1')) # <type 'str'>print(type(ObjectCreator)) # <type 'type'>print(type(ObjectCreator())) # <class '__main__.ObjectCreator'>type(name, bases, attrs)name: 类名;
bases: 父类的元组(用于继承,可以为空);
attrs: 包含属性名称和值的字典;
class MyShinyClass(object): passMyShinyClass = type('MyShinyClass', (), {}) # 返回类对象print(MyShinyClass) # 输出结果:<class '__main__.MyShinyClass'>print(MyShinyClass()) # 创建类的实例,输出结果:<__main__.MyShinyClass object at 0x8997cec>
class Foo(object): bar = TrueFoo = type('Foo', (), {'bar':True})# 使用Foo类print(Foo) # 输出:<class '__main__.Foo'>print(Foo.bar) # 输出:Truef = Foo()print(f) # 输出:<__main__.Foo object at 0x8a9b84c>print(f.bar) # 输出:Trueclass FooChild(Foo):pass
# 动态继承FooFooChild = type('FooChild', (Foo,), {})print(FooChild) # 输出:<class '__main__.FooChild'># bar属性来至于Foo类print(FooChild.bar) # 输出:True# 向FooChild类动态添加echo_bar函数FooChild = type('FooChild', (Foo,), {'echo_bar': echo_bar})print(hasattr(Foo, 'echo_bar')) # 输出:Falseprint(hasattr(FooChild, 'echo_bar')) # 输出:Truemy_foo = FooChild()my_foo.echo_bar() # 输出:True
def echo_bar_more(self): print('yet another method')FooChild.echo_bar_more = echo_bar_moreprint(hasattr(FooChild, 'echo_bar_more')) # 输出:True# 通过元类创建类MyClass = MetaClass()# 通过类创建类实例my_object = MyClass()
MyClass = type('MyClass', (), {})age = 35print(age.__class__) # 输出:<type 'int'>name = 'bob'print(name.__class__) # 输出:<type 'str'>def foo():passprint(foo.__class__) # 输出:<type 'function'>class Bar(object):passb = Bar()print(b.__class__) # 输出:<class '__main__.Bar'>
print(age.__class__.__class__) # 输出:<type 'type'>print(name.__class__.__class__) # 输出:<type 'type'>print(foo.__class__.__class__) # 输出:<type 'type'>print(b.__class__.__class__) # 输出:<type 'type'># 元类(metaclass)将自动为该函数传递与type函数相同的参数值def upper_attr(class_name, class_parents, class_attrs):'''返回一个类对象,将该对象的所有属性的名称都变成大写'''# 除了以'__'开头的属性外,其他的属性都变成大写uppercase_attrs = {attr if attr.startswith('__') else attr.upper(): vfor attr, v in class_attrs.items()}# 使用type动态创建类对象return type(class_name, class_parents, uppercase_attrs)# 使用metaclass指定元类函数,系统会自动调用元类函数(upper_attr)# 为该函数传递的参数值与调用type函数动态创建Foo类时传入的参数值相同class Foo(metaclass=upper_attr):bar = 'bip'print(hasattr(Foo, 'bar')) # 输出:Falseprint(hasattr(Foo, 'BAR')) # 输出:True# bar已经被元类函数自动改成了BARprint(Foo.BAR) # 输出:bip
关注「极客起源」公众号,加星标,不错过精彩技术干货
赞 (0)
