实例化后在Currency类内部创建动态SpecificAsset类的实现问题
解决方案
核心问题梳理
create_asset_class作为Currency的实例方法,缺少self参数- 动态类的父类直接指定为
SpecificAsset即可,其绑定的元类会自动被继承,无需额外配置 - 自定义
__init__逻辑存在错误:未定义argnames参数、调用父类__init__时传参不符合要求 - 动态类命名逻辑错误,误用了
self.name而不是传入的name参数
修正后的可运行代码
from datetime import datetime from decimal import Decimal class AssetMeta(type): asset_classes = {} def __new__(cls, clsname, superclasses, attributedict): if clsname in cls.asset_classes: raise ValueError("Redefinition of Asset subclass '{}'".format(clsname)) tp = type.__new__(cls, clsname, superclasses, attributedict) cls.asset_classes[clsname] = tp return tp class SpecificAsset(metaclass=AssetMeta): def __init__(self, owner, priAssetType, priAsset, qty, altAsset): self.id = id(self) self.owner = owner self.creationDate = datetime.now() self.priType = priAssetType self.primary = priAsset self.holdingQty = Decimal(qty) self.initialQty = Decimal(qty) self.primary.holdingQty += Decimal(qty) self.altType = 'quote' if self.priType == 'base' else 'base' self.alternate = altAsset self.altValue = Decimal('0.00') self.USDpointer = getattr(self.primary, 'pointer', None) self.pending = False class Currency: count = 0 def __init__(self, name): Currency.count += 1 self.id = id(self) self.name = name self.bases = {} self.quotes = {} self.holdingQty = Decimal('0.00') self.pointer = None def point_to(self, CUR): self.pointer = CUR def create_asset_class(self, name, BaseClass=SpecificAsset): # 可选优化:自动填充priAsset为当前Currency实例,减少调用传参 def __init__(self, owner, priAssetType, qty, altAsset, priAsset=None): priAsset = priAsset or self super().__init__(owner, priAssetType, priAsset, qty, altAsset) # 父类直接填BaseClass即可,元类会自动继承 newclass = type(name, (BaseClass,), {"__init__": __init__}) return newclass
使用示例
# 初始化币种 btc = Currency('BTC') usdt = Currency('USDT') # 为BTC-USDT交易对创建专属资产类 BTC_USDT_Asset = btc.create_asset_class(name='BTC_USDT_Asset') # 实例化资产类(对应买入操作) owner = None # 替换为实际的Owner类实例 asset = BTC_USDT_Asset( owner=owner, priAssetType='base', qty='0.1', altAsset=usdt ) # 验证属性 print(asset.primary.name) # 输出 BTC print(asset.holdingQty) # 输出 0.1 print(btc.holdingQty) # 输出 0.1
扩展说明
- 如果需要为动态生成的资产类添加专属方法/属性,直接在type创建类的第三个参数字典中添加即可
- 元类AssetMeta已内置同名类重复创建的校验,无需额外加判断逻辑
- 不需要自动填充priAsset的话可以删掉自定义的
__init__,直接继承父类的初始化逻辑即可
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

