Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用python创建动态方法?_Python_Django - Fatal编程技术网

如何使用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'

对于我的项目,我需要动态创建自定义(类)方法

我发现在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') 

    #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_过滤器。对不起,我指的是自定义动态生成的类方法。因此,您的继承示例不会回答这个问题。如果我不搜索任何内容,则说明您应该使用动态类或动态函数/方法。也许评论中的“动态”一词有误导性?哇,我今天真的学到了一些东西,虽然我还没有检查答案,但这真的会帮助我构建它!另外,你提到的关于元类的参考文献也很棒!赏金花得很好:)好吧,它还不起作用。仍在努力,因此任何想法都将不胜感激!您是否尝试过添加一个简单的过滤器,它可能只适用于一种情况?试着看看是什么让它起作用,以及你可能错过了什么。