Python中的函数参数的默认值[duplicate]

时间:2022-11-05 11:12:22

Possible Duplicate:
default value of parameter as result of instance method

可能重复:作为实例方法的参数的默认值

While it is possible to set default values to function parameters in python:

在python中,可以将默认值设置为函数参数:

def my_function(param_one='default')
    ...

It seems not to be possible to access the current instance (self):

似乎不可能访问当前实例(self):

class MyClass(..):

    def my_function(self, param_one=self.one_of_the_vars):
        ...

My question(s):

我的问题:

  • Is this true that I cannot access the current instance to set the default parameter in functions?
  • 我不能访问当前实例来设置函数中的默认参数,这是真的吗?
  • If it is not possble: what are the reasons and is it imaginable that this will be possible in future versions of python?
  • 如果它不是所有的:是什么原因,并且可以想象这在未来的python版本中是可能的吗?

4 个解决方案

#1


51  

It's written as:

这是写为:

def my_function(self, param_one=None): # Or custom sentinel if None is vaild
    if param_one is None:
        param_one = self.one_of_the_vars

And I think it's safe to say that will never happen in Python due to the nature that self doesn't really exist until the function starts... (you can't reference it, in its own definition - like everything else)

我认为可以肯定地说,这在Python中是不会发生的,因为在函数开始之前,self实际上并不存在。(你不能像其他事物一样,用自己的定义来引用它)

For example: you can't do d = {'x': 3, 'y': d['x'] * 5}

例如:你不能做d = {“x”:3,“y”:d[x]* 5 }

#2


12  

There is much more to it than you think. Consider the defaults to be static (=constant reference pointing to one object) and stored somewhere in the definition; evaluated at method definition time; as part of the class, not the instance. As they are constant, they cannot depend on self.

它比你想象的要多得多。假设默认值是静态的(=指向一个对象的常量引用),并存储在定义中的某个位置;在方法定义时间进行评估;作为类的一部分,而不是实例。因为他们是不变的,他们不能依靠自己。

Here is an example. It is counterintuitive, but actually makes perfect sense:

这是一个例子。这是违反直觉的,但实际上很有道理:

def add(item, s=[]):
    s.append(item)
    print len(s)

add(1)     # 1
add(1)     # 2
add(1, []) # 1
add(1, []) # 1
add(1)     # 3

This will print 1 2 1 1 3.

这将打印1 2 1 3。

Because it works the same way as

因为它和

default_s=[]
def add(item, s=default_s):
    s.append(item)

Obviously, if you modify default_s, it retains these modifications.

显然,如果您修改default_s,它将保留这些修改。

There are various workarounds, including

有各种各样的变通方法,包括

def add(item, s=None):
    if not s: s = []
    s.append(item)

or you could do this:

或者你可以这样做:

def add(self, item, s=None):
    if not s: s = self.makeDefaultS()
    s.append(item)

Then the method makeDefaultS will have access to self.

然后这个方法makeDefaultS将会访问self。

Another variation:

另一个变化:

import types
def add(item, s=lambda self:[]):
    if isinstance(s, types.FunctionType): s = s("example")
    s.append(item)

here the default value of s is a factory function.

这里s的默认值是一个工厂函数。

You can combine all these techniques:

你可以结合所有这些技术:

class Foo:
    import types
    def add(self, item, s=Foo.defaultFactory):
        if isinstance(s, types.FunctionType): s = s(self)
        s.append(item)

    def defaultFactory(self):
        """ Can be overridden in a subclass, too!"""
        return []

#3


3  

Default value for parameters are evaluated at "compilation", once. So obviously you can't access self. The classic example is list as default parameter. If you add elements into it, the default value for the parameter changes!

参数的默认值在“编译”时计算一次。显然你不能访问self。典型的例子是列表作为默认参数。如果向其中添加元素,则参数的默认值将会改变!

The workaround is to use another default parameter, typically None, and then check and update the variable.

解决方案是使用另一个默认参数(通常为None),然后检查和更新变量。

#4


2  

There are multiple false assumptions you're making here - First, function belong to a class and not to an instance, meaning the actual function involved is the same for any two instances of a class. Second, default parameters are evaluated at compile time and are constant (as in, a constant object reference - if the parameter is a mutable object you can change it). Thus you cannot access self in a default parameter and will never be able to.

这里有多个错误假设——首先,函数属于一个类,而不是一个实例,这意味着所涉及的实际函数对于类的任意两个实例都是相同的。其次,默认参数在编译时进行计算,并且是常量(比如,常量对象引用——如果参数是可变对象,则可以更改它)。因此,您无法在默认参数中访问self,并且永远无法访问self。

#1


51  

It's written as:

这是写为:

def my_function(self, param_one=None): # Or custom sentinel if None is vaild
    if param_one is None:
        param_one = self.one_of_the_vars

And I think it's safe to say that will never happen in Python due to the nature that self doesn't really exist until the function starts... (you can't reference it, in its own definition - like everything else)

我认为可以肯定地说,这在Python中是不会发生的,因为在函数开始之前,self实际上并不存在。(你不能像其他事物一样,用自己的定义来引用它)

For example: you can't do d = {'x': 3, 'y': d['x'] * 5}

例如:你不能做d = {“x”:3,“y”:d[x]* 5 }

#2


12  

There is much more to it than you think. Consider the defaults to be static (=constant reference pointing to one object) and stored somewhere in the definition; evaluated at method definition time; as part of the class, not the instance. As they are constant, they cannot depend on self.

它比你想象的要多得多。假设默认值是静态的(=指向一个对象的常量引用),并存储在定义中的某个位置;在方法定义时间进行评估;作为类的一部分,而不是实例。因为他们是不变的,他们不能依靠自己。

Here is an example. It is counterintuitive, but actually makes perfect sense:

这是一个例子。这是违反直觉的,但实际上很有道理:

def add(item, s=[]):
    s.append(item)
    print len(s)

add(1)     # 1
add(1)     # 2
add(1, []) # 1
add(1, []) # 1
add(1)     # 3

This will print 1 2 1 1 3.

这将打印1 2 1 3。

Because it works the same way as

因为它和

default_s=[]
def add(item, s=default_s):
    s.append(item)

Obviously, if you modify default_s, it retains these modifications.

显然,如果您修改default_s,它将保留这些修改。

There are various workarounds, including

有各种各样的变通方法,包括

def add(item, s=None):
    if not s: s = []
    s.append(item)

or you could do this:

或者你可以这样做:

def add(self, item, s=None):
    if not s: s = self.makeDefaultS()
    s.append(item)

Then the method makeDefaultS will have access to self.

然后这个方法makeDefaultS将会访问self。

Another variation:

另一个变化:

import types
def add(item, s=lambda self:[]):
    if isinstance(s, types.FunctionType): s = s("example")
    s.append(item)

here the default value of s is a factory function.

这里s的默认值是一个工厂函数。

You can combine all these techniques:

你可以结合所有这些技术:

class Foo:
    import types
    def add(self, item, s=Foo.defaultFactory):
        if isinstance(s, types.FunctionType): s = s(self)
        s.append(item)

    def defaultFactory(self):
        """ Can be overridden in a subclass, too!"""
        return []

#3


3  

Default value for parameters are evaluated at "compilation", once. So obviously you can't access self. The classic example is list as default parameter. If you add elements into it, the default value for the parameter changes!

参数的默认值在“编译”时计算一次。显然你不能访问self。典型的例子是列表作为默认参数。如果向其中添加元素,则参数的默认值将会改变!

The workaround is to use another default parameter, typically None, and then check and update the variable.

解决方案是使用另一个默认参数(通常为None),然后检查和更新变量。

#4


2  

There are multiple false assumptions you're making here - First, function belong to a class and not to an instance, meaning the actual function involved is the same for any two instances of a class. Second, default parameters are evaluated at compile time and are constant (as in, a constant object reference - if the parameter is a mutable object you can change it). Thus you cannot access self in a default parameter and will never be able to.

这里有多个错误假设——首先,函数属于一个类,而不是一个实例,这意味着所涉及的实际函数对于类的任意两个实例都是相同的。其次,默认参数在编译时进行计算,并且是常量(比如,常量对象引用——如果参数是可变对象,则可以更改它)。因此,您无法在默认参数中访问self,并且永远无法访问self。