python中类的创建_如何在python中为类动态创建类方法

1.基本思想:使用额外的类来保存方法

我找到了一种有意义的工作方式:

首先,我们定义这样的BaseClass:

class MethodPatcher:

@classmethod

def patch(cls, target):

for k in cls.__dict__:

obj = getattr(cls, k)

if not k.startswith('_') and callable(obj):

setattr(target, k, obj)

现在我们有了一个原始的类:

class MyClass(object):

def a(self):

print('a')

然后,我们定义要添加到新的2586361037498898876928类上的新方法:

(在这种情况下,请勿使方法名称以2586361037498898876928开头)

class MyPatcher(MethodPatcher):

def b(self):

print('b')

然后致电:

MyPatcher.patch(MyClass)

因此,您会发现将2586361037498898876928新方法添加到原始@patch_method:

obj = MyClass()

obj.a() # which prints an 'a'

obj.b() # which prints a 'b'

2.使语法不太冗长,我们使用类装饰器

现在,如果我们声明了2586361037498898876928,我们需要做两件事:

定义@patch_method的子级MethodPatcher,其中包含要添加的其他方法

致电MethodPatcher

因此,我们很快发现可以使用装饰器简化第二步:

我们定义一个装饰器:

def patch_methods(model_class):

def do_patch(cls):

cls.patch(model_class)

return do_patch

我们可以像这样使用它:

@patch_methods(MyClass)

class MyClassPatcher(MethodPatcher):

def extra_method_a(self):

print('a', self)

@classmethod

def extra_class_method_b(cls):

print('c', cls)

# !!ATTENTION!! the effect on declaring staticmethod here may not work as expected:

# calling this method on an instance will take the self into the first argument.

# @staticmethod

# def extra_static_method_c():

# print('c')

3.一起包装

因此,我们现在可以将25863610374988988769和@patch_method的定义放到一个模块中:

# method_patcher.py

class MethodPatcher:

@classmethod

def patch(cls, target):

for k in cls.__dict__:

obj = getattr(cls, k)

if not k.startswith('_') and callable(obj):

setattr(target, k, obj)

def patch_methods(model_class):

def do_patch(cls):

cls.patch(model_class)

return do_patch

因此我们可以自由使用它:

from method_patcher import ModelPatcher, patch_model

4.最终解决方案:更简单的声明

很快我发现2586361037498898876928类不是必需的,而2586361037498876976929装饰器可以完成此工作,因此最终我们只需要2586361037498898876930:

def patch_methods(model_class):

def do_patch(cls):

for k in cls.__dict__:

obj = getattr(cls, k)

if not k.startswith('_') and callable(obj):

setattr(model_class, k, obj)

return do_patch

用法变为:

@patch_methods(MyClass)

class MyClassPatcher:

def extra_method_a(self):

print('a', self)

@classmethod

def extra_class_method_b(cls):

print('c', cls)

# !!ATTENTION!! the effect on declaring staticmethod here may not work as expected:

# calling this method on an instance will take the self into the first argument.

# @staticmethod

# def extra_static_method_c():

# print('c')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值