Python 如何将参数名作为参数传递?

Python 如何将参数名作为参数传递?,python,django,Python,Django,我有以下代码: hobbies2 = form.cleaned_data.pop('hobbies2') PersonneHobby.objects.filter(personne=obj).delete() for pk_str in hobbies2: try: hobby = TagTraduit.objects.get(pk=int(pk_str)) p = PersonneHobby.objects.create(personne=obj,

我有以下代码:

hobbies2 = form.cleaned_data.pop('hobbies2')
PersonneHobby.objects.filter(personne=obj).delete()
for pk_str in hobbies2:
    try:
        hobby = TagTraduit.objects.get(pk=int(pk_str))
        p = PersonneHobby.objects.create(personne=obj,
                                         hobby=hobby)
        p.save()
    except ValueError:
        break  # hack in the POST
    except LookupError:
        break  # hack in the POST
我将为4个不同的字段提供相同的代码,例如
程序

programmes2 = form.cleaned_data.pop('programmes2')
PersonneProgramme.objects.filter(personne=obj).delete()
for pk_str in programmes2:
    try:
        programme2 = TagTraduit.objects.get(pk=int(pk_str))
        p = PersonneProgramme.objects.create(personne=obj,
                                             programme=programme2)
        p.save()
    except ValueError:
        break  # hack = tout stopper
    except LookupError:
        break  # hack = tout stopper
完全相同的代码,只更改字段的名称。所以我想做一个泛型函数,并像这样调用它:

def update_field(post_field, class_field, **kwargs):
    try:
        values = form.cleaned_data.pop(post_field)
        class_field.objects.filter(personne=obj).delete()
        for pk_str in values:
            try:
                v = TagTraduit.objects.get(pk=int(pk_str))
                p = class_field.objects.create(**{'personne': obj,
                                                  field_name: v})
                p.save()
            except ValueError:
                break  # hack = tout stopper
            except LookupError:
                break  # hack = tout stopper
    except KeyError:
        pass
update_field('programmes2', PersonneProgramme, 'programme')
update_field('hobbies2', PersonneHobby, 'hobby')
我的主要问题是最后一个参数,它是在数据库中创建记录时要使用的字段的名称

如何操作?

您可以执行以下操作:

def update_field(..., field_name):
   ...
   tag = TagTraduit.objects.get(pk=int(pk_str))
   p = PersonneProgramme.objects.create(**{'personne': obj, field_name: tag})

您可以使用任意数量的关键字参数(
**
)并在函数中插入计算出的附加参数:

def update_field(field, update_this, **kwargs):
     ...
     kwargs[update_this] = TagTraduit.objects.get(pk=int(pk_str))
     p = field.objects.create(**kwargs)
     ...
这允许您这样称呼它:

update_field(PersonneHobby, 'hobby', personne=obj)
update_field(PersonneProgramme, 'programme', personne=obj)

我会同意@MSeifert所说的。如果你想让你写的任何东西都能工作,我的意思是只使用位置参数

def f(a,b,c):
    a.func(b=b, c=c)  # this is perfectly legal
但更好的办法是

def f(a, **kwargs):
    a.func(**kwargs)  # kwargs is passed as a dict. **kwargs is
                      # unpacking it into key1=val1, key2=val2, ... 

我用kwargs更新了我的问题,你会明白我的意思。@Sayse如果你出于某种原因恨我,你可以这么说。不,更多。看第一个街区。他不确定从
(a,b,c)
收集
c
作为
(…,c=c)
什么?我真的不恨任何人,更不用说网站上的陌生人了。我刚才指出,您刚刚展示了一段代码(这行不通),然后说其他人的答案是正确的,这是不必要的,对所说的答案进行表决会更有成效。第一个,
b
c
都是值,因此,它们的值与应该包含该值的关键字的名称的值不同。@Sayse好吧,你错了
b
c
根本不是值,它们是名称/标识符。因此
a.func(b=b,c=c)
是合法的,它代表
a.func(a=,b=)
。Python变量与C变量不同。在C++中,你不能做。叫他们“名字”更合适。我用kwargs更新了我的问题,你会明白我的意思。