如何使用python创建动态方法?
对于我的项目,我需要动态创建自定义(类)方法 我发现在Python中并不容易:如何使用python创建动态方法?,python,django,Python,Django,对于我的项目,我需要动态创建自定义(类)方法 我发现在Python中并不容易: class UserFilter(django_filters.FilterSet): ''' This filter is used in the API ''' # legacy below, this has to be added dynamically #is_field_type1 = MethodFilter(action='filter_field_type1'
class UserFilter(django_filters.FilterSet):
'''
This filter is used in the API
'''
# legacy below, this has to be added dynamically
#is_field_type1 = MethodFilter(action='filter_field_type1')
#def filter_field_type1(self, queryset, value):
# return queryset.filter(related_field__field_type1=value)
class Meta:
model = get_user_model()
fields = []
但它给了我错误(和头痛…)。这可能吗
我试图使代码介于#遗留动态之间
我找到的一个方法是动态创建类
def create_filter_dict():
new_dict = {}
for field in list_of_fields:
def func(queryset, value):
_filter = {'stableuser__'+field:value}
return queryset.filter(**_filter)
new_dict.update({'filter_'+field: func})
new_dict.update({'is_'+field: MethodFilter(action='filter_'+field)})
return new_dict
meta_model_dict = {'model': get_user_model(), 'fields':[]}
meta_type = type('Meta',(), meta_model_dict)
filter_dict = create_filter_dict()
filter_dict['Meta'] = meta_type
UserFilter = type('UserFilter', (django_filters.FilterSet,), filter_dict)
然而,这是给我的
TypeError at /api/v2/users/
func() takes 2 positional arguments but 3 were given
有人知道如何解决这个难题吗?你可以使用。以下是如何使用它的示例:
class UserFilter:
@classmethod
def filter_field(cls, queryset, value, field = None):
# do somthing
return "{0} ==> {1} {2}".format(field, queryset, value)
@classmethod
def init(cls,list_of_fields ):
for field in list_of_fields:
ff = lambda cls, queryset, value, field=field: cls.filter_field(queryset, value, field )
setattr(cls, 'filter_'+field, classmethod( ff ))
UserFilter.init( ['a','b'] )
print(UserFilter.filter_a(1,2)) # a ==> 1 2
print(UserFilter.filter_b(3,4)) # b ==> 3 4
你要求的是:
自定义(类)方法
因此,我们获取一个现有类并派生一个子类,您可以在其中添加新方法或覆盖原始现有类的方法(查看原始类的代码以获取所需的方法),如下所示:
from universe import World
class NewEarth(World.Earth):
def newDirectionUpsideDown(self,direction):
self.rotationDirection = direction
世界的所有其他方法和特征。地球适用于新地球,只有你现在可以改变方向,让世界变成你的新方式
覆盖类的现有方法非常简单
class NewEarth(World.Earth):
def leIitRain(self,amount): # let's assume leIitRain() is a standard-function of our world
return self.asteroidStorm(amount) #let's assume this is possible Method of World.Earth
因此,如果有人喜欢在地球上洗个冷水澡,他/她/它或其他任何东西都会为玩具大理石的燃烧方式的新发展腾出空间
因此,在学习python的过程中要有乐趣,不要从复杂的事情开始
如果我完全错了,你可以更详细地解释你的问题,这样比我聪明的人可以分享他们的智慧
异常值:“UserFilter”对象没有属性“已绑定”
出现此错误是因为生成的类方法未绑定到任何类。要将它们绑定到类,需要使用setattr()
在控制台上尝试以下操作:
class MyClass(object):
pass
@classmethod
def unbound(cls):
print "Now I'm bound to ", cls
print unbound
setattr(MyClass, "bound", unbound)
print MyClass.bound
print MyClass.bound()
回溯:
UserFilter=type('Foo',(django_filters.FilterSet,),create_filter_dict()。update({'Meta':type('Meta',(),{'model'):
get_user_model(),'fields':[]})TypeError:type()参数3必须
听天由命,而不是一无所获
现在,这是失败的,因为dict.update()不返回相同的实例,而是不返回任何实例。这个问题很容易解决
class_dict = create_filter_dict()
class_dict.update({'Meta':type('Meta',(), {'model': get_user_model(), 'fields':[]})}
UserFilter = type('Foo', (django_filters.FilterSet, ), class_dict))
然而,看看代码看起来有多混乱。我建议你尽量保持冷静
您编写的代码更清晰,即使它需要多写几行。从长远来看,代码将更容易为您和您的团队维护
meta_model_dict = {'model': get_user_model(), 'fields':[]}
meta_type = type('Meta',(), meta_model_dict)
filter_dict = create_filter_dict()
filter_dict['Meta'] = meta_type
UserFilter = type('Foo', (django_filters.FilterSet,), filter_dict)
此代码可能并不完美,但它比您发布的原始代码行更具可读性:
UserFilter = type('Foo', (django_filters.FilterSet, ), create_filter_dict().update({'Meta':type('Meta',(), {'model': get_user_model(), 'fields':[]})}))
并且消除了一个已经有点难理解的概念的复杂性
您可能想了解元类。也许您可以覆盖类的新方法。我可以向你推荐或张贴有关这方面的文章
另一个选择是,可能您没有正确地添加过滤器,或者以django不期望的方式添加过滤器?这可以解释为什么没有错误,但没有调用任何函数。这可能是对问题进行诊断的最糟糕的方式,而不是创建classmethod的方式。你到底想在这里干什么?您在另一个类定义中有一个类定义(这是完全可能的,只是肯定不是您想要的)。。。你到底想解决什么问题?显示完整的回溯试图更改
\uuu init\uuuu()
中的FilterSet
类已经太晚了。此时,已完成所有相关设置。您需要动态构建FilterSet
类(type()
),或者深入django筛选器并找到更好的方法。在编辑3中出现的错误是因为dict.update
返回None
,而不是dict
。它不会给我任何错误,但也不会将筛选器添加到查询中。我认为您的代码不能很好地使用django_过滤器。对不起,我指的是自定义动态生成的类方法。因此,您的继承示例不会回答这个问题。如果我不搜索任何内容,则说明您应该使用动态类或动态函数/方法。也许评论中的“动态”一词有误导性?哇,我今天真的学到了一些东西,虽然我还没有检查答案,但这真的会帮助我构建它!另外,你提到的关于元类的参考文献也很棒!赏金花得很好:)好吧,它还不起作用。仍在努力,因此任何想法都将不胜感激!您是否尝试过添加一个简单的过滤器,它可能只适用于一种情况?试着看看是什么让它起作用,以及你可能错过了什么。