python元类使用场景_python 元类的使用

class Animal(object):

"""a class representing an animal"""

def __init__(self,name):

self.name = name

def eat(self):

pass

def go_to_vet(self):

pass

animal = Animal('cat')

print(type(Animal))

print(animal)

#用type方式创建类******************************************************************

def init(self,name):

self.name = name

def eat(self):

pass

def go_to_vet(self):

pass

Animal = type('Animal',(object,),

{'__doc__':"a class representing an animal",'__init__':init,

'eat':eat,'go_to_vet':go_to_vet})

animal = Animal('dog')

print(animal)

#创建子类

def meow(self):

return None

def purr(self):

return None

Cat = type('Cat',(Animal,),{

'meow':meow,

'purr':purr

})

cat = Cat(name='xiaohuang')

print(cat)

print(type(Cat))

#元类示例******************************************************************

class Meta(type):

"""a metaclass that adds no actual functionality"""

def _(cls,name,bases,attrs):

"""

:param name: 类型:字符串 类名

:param bases: 类型:元组,继承的基类

:param attrs: 类型:字典 属性

:return: 类

"""

return super(Meta, cls).__new__(cls,name,bases,attrs)

#何时使用元类******************************************************************

# 1.说明性类声明,现有示例django模型声明

# 2.类验证 (foo 和 bar属性两个只能包含一个)

class FooOrbar(type):

def __new__(cls, name,bases,attrs):

if 'foo' in attrs and 'bar' in attrs:

raise TypeError('Class %s cannot contain both foo and bar'%name)

if 'foo' not in attrs and 'bar' not in attrs:

raise TypeError('Class %s must provide either foo or bar'%name)

return super(FooOrbar,cls).__new__(cls,name,bases,attrs)

class Valid(metaclass=FooOrbar):

foo = 42

v = Valid()

class Invalid(metaclass=FooOrbar):

foo =41

# 以上实现存在一个问题,他的子类并不会继承该功能,原因是元类直接检查attrs属性,但这只包含所声明的类属性集,

# 他并不知道继承自基类的属性

# class AlsoValid(Valid):

# pass

# 改进如下

class FooOrBarUpdate(type):

def __new__(cls, name,bases,attrs):

"""实例化,从基类中获取了所有的属性"""

answer = super(FooOrBarUpdate, cls).__new__(cls,name,bases,attrs)

if hasattr(answer,'foo') and hasattr(answer,'bar'):

raise TypeError('Class %s cannot contain both foo and bar'%name)

if not hasattr(answer,'foo') and not hasattr(answer,'bar'):

raise TypeError('Class %s must provide either foo or bar' % name)

return answer

# 3.非继承性

class Meta1(type):

def __new__(cls, name,bases,attrs):

if attrs.get('abstract',False):

return super(Meta1,cls).__new__(cls,name,bases,attrs)

class SubClass(metaclass=Meta1):

abstract = False

# 以上元类定义存在一个问题,任何子类都需要显示的声明自己并不是抽象类

# 改进如下 :

class MetaUpdate1(type):

def __new__(cls, name,bases,attrs):

if attrs.pop('abstract',False):

return super(MetaUpdate1, cls).__new__(cls,name,bases,attrs)

#meta-coding***************************************************************

class Logged(type):

""""a meta class that cause classes that it creates to log their function calls"""

def __new__(cls, name,bases,attrs):

for k,v in attrs.items():

if callable(v):

attrs[k] = cls.log_call(v)

return super(Logged, cls).__new__(cls,name,bases,attrs)

@staticmethod

def log_call(v):

def inner(*args,**kwargs):

try:

response = v(*args,**kwargs)

print('%s函数被调用,参数为%s,字典关键字为:%s.'%(v.__name__,args,kwargs))

return response

except Exception as e:

print('%s函数被调用,抛出异常:%s'%(v.__name__,e))

raise e

return inner

class MyClass(metaclass=Logged):

def foo(self):

pass

def bar(self):

raise TypeError('oh,noes')

obj = MyClass()

obj.foo()

obj.bar()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中,`__`(下划线)用于表示私有成员(private members)。当一个属性或方法前加上双下划线(`__`)时,它会成为类内部的一个隐藏元素,意味着外部无法直接访问该成员。 ### 私有成员的作用 1. **封装**:私有成员有助于限制对类内部数据的直接访问,可以保护类的数据结构不受外界意外更改的影响,提高程序的安全性和健壮性。 2. **隐藏实现细节**:通过将一些属性标记为私有,可以让使用者只关注其功能而不必关心底层实现细节,这对于设计模块化的、易于维护的代码库非常有用。 ### 如何创建私有成员 要在Python中创建私有成员,只需要在其名称前面添加两个下划线即可: ```python class MyClass: def __init__(self): self.__private_attribute = "This is a private attribute." def public_method(self): print("Public method called.") ``` 在这个例子中,`__private_attribute`是一个私有属性,而`public_method`是一个公共方法。尝试从外部访问`__private_attribute`将导致`AttributeError`错误。 ### 使用场景示例 假设我们有一个简单的银行账户类,我们需要保护账户余额,并仅允许存款和取款操作: ```python class Account: def __init__(self, balance=0): self.__balance = balance def deposit(self, amount): self.__balance += amount def withdraw(self, amount): if amount <= self.__balance: self.__balance -= amount else: print("Insufficient funds.") def get_balance(self): return self.__balance ``` 在这里,`__balance`是一个私有属性,只有通过提供的`deposit()`, `withdraw()` 和 `get_balance()`等公有方法才能修改或获取。这种封装使得类能够更安全地管理其内部状态。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值