gpt4 book ai didi

python - 如何覆盖函数定义中 **kwargs 的含义,以便将字典解压到函数 def 的默认参数中?

转载 作者:行者123 更新时间:2023-12-01 04:01:23 30 4
gpt4 key购买 nike

在Python中,是否可以在函数定义中解压关键字args的字典?据我所知,这是不可能的,因为双星语法有两个独立的定义。仅当调用函数时才能解包,而在定义函数时则不能解包。这是真的?如果是这样,有没有办法解决它来完成类似于我想做的事情?换句话说,我可以覆盖此行为吗?

双星有两种用途** 。一、**可用于将字典(并将其解压)传递给函数。二、**kwargs可以在定义函数时使用来指示未指定数量的关键字参数。据我所知,这是 ** 的两个完全独立(尽管逻辑上一致)的定义。 .
详细说明在这里:
What does ** (double star) and * (star) do for Python parameters?

每个的简单示例。

def print_args(**kwargs):
print kwargs

print_args(one='this', two='that')
# {'two': 'that', 'one': 'this'}

def print_kw(one=None, two=None):
print one; print two

print_kw(**{'one':'this', 'two':'that'})
# this
# that

我想做的是:

packed_keywords = {'apple':'red', 'peach':'fuzzy'}
def print_unpacked_kw(**packed_keywords):
print apple; print peach

print_unpacked()
# NameError: global name 'apple' is not defined
# I'd like this to print out "red fuzzy"

为了进行比较,这里有一个类似代码的示例,未解压。这个版本可以工作,但没有按照我的意愿使用关键字 args 的字典。

def print_typed_kw(apple='red', peach='fuzzy'):     
print apple; print peach

print_typed_kw()
# red
# fuzzy

编辑:我为什么要这样做?

上下文:
这个解释是针对 scikit-learn 的。如果您不熟悉这个库,最好忽略此上下文部分的其余部分。这个问题是在编写将进入管道的转换器类的背景下出现的。具体来说,我正在创建一个转换器,它将返回来自回归器的预测。我的想法是使用这个预测作为特征联合中的一个特征,该特征将进入另一个下游分类器。

管道的好处之一是在网格搜索中设置参数以优化超参数。根据我的经验,只有在 __init__ 中将参数定义为参数时,才可以通过这种方式访问​​用户定义函数的参数。估计器类的构造函数。这是我的类(class):

class RandForestTransformer(BaseEstimator, TransformerMixin):
"""
Takes a random forest (or could be any classifier) and uses
predict as output for transform, which can then be used as
a feature in another FeatureUnion and classifier.
"""
def __init__(self,
n_estimators=10, criterion='mse',
max_depth=None, min_samples_split=2,
min_samples_leaf=1, min_weight_fraction_leaf=0.0,
max_features='auto', max_leaf_nodes=None,
bootstrap=True, oob_score=False, n_jobs=1,
random_state=None, verbose=0, warm_start=False):
self.rf = RandomForestRegressor()
def fit(self, X, y):
self.rf = self.rf.fit(X, y)
return self
def transform(self, X, y=None):
return self.rf.predict(X)

我希望能够将字典传递给 __init__定义,以便我可以轻松更改各个参数,而无需每次都重新定义整个类。

编辑2:
关于我的具体问题,我想感谢 @j-a 建议查看 scikit-learn BaseEstimator 代码。
https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/base.py

BaseEstimator 的类定义明确指出参数必须在 __init__ 中给出对其进行内省(introspection)以供管道使用。

class BaseEstimator(object):
"""Base class for all estimators in scikit-learn
Notes
-----
All estimators should specify all the parameters that can be set
at the class level in their ``__init__`` as explicit keyword
arguments (no ``*args`` or ``**kwargs``).
"""

最佳答案

您正在尝试将包罗万象的 **kwargs 参数应用到您的 locals 命名空间中。由于 Python 中的优化限制,您无法执行此操作;局部变量实际上是一个 C 数组,解释器在其中通过索引查找变量(为函数生成的字节码使用索引而不是字符串来引用局部变量)。

所以不,你不能这样做。而且您不需要这样做,因为您的函数体不是动态的。无论如何,您必须在函数体中引用 applepeach,因此,如果您需要访问更多关键字参数,则必须更新该代码;更新主体和函数参数列表时没有区别。

在更广泛的上下文中,您的 RandForestTransformer.__init__ 方法不使用任何关键字参数,因此定义所有这些名称是没有意义的。 可能是 scikit-learn 正在该方法上使用内省(introspection)来查看管道使用的变量,但如果是这种情况,则将关键字参数列表替换为 **kwargs 也不起作用,因为这会夺走内省(introspection)的唯一来源。

关于python - 如何覆盖函数定义中 **kwargs 的含义,以便将字典解压到函数 def 的默认参数中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36445710/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com