Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

default value in constructor not unique across objects #53008

Closed
bolt mannequin opened this issue May 19, 2010 · 3 comments
Closed

default value in constructor not unique across objects #53008

bolt mannequin opened this issue May 19, 2010 · 3 comments
Labels
type-bug An unexpected behavior, bug, or error

Comments

@bolt
Copy link
Mannequin

bolt mannequin commented May 19, 2010

BPO 8762
Nosy @bitdancer

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2010-05-19.02:05:20.179>
created_at = <Date 2010-05-19.00:35:32.793>
labels = ['type-bug', 'invalid']
title = 'default value in constructor not unique across objects'
updated_at = <Date 2010-05-19.02:08:05.083>
user = 'https://bugs.python.org/bolt'

bugs.python.org fields:

activity = <Date 2010-05-19.02:08:05.083>
actor = 'ysj.ray'
assignee = 'none'
closed = True
closed_date = <Date 2010-05-19.02:05:20.179>
closer = 'r.david.murray'
components = []
creation = <Date 2010-05-19.00:35:32.793>
creator = 'bolt'
dependencies = []
files = []
hgrepos = []
issue_num = 8762
keywords = []
message_count = 3.0
messages = ['106018', '106027', '106029']
nosy_count = 3.0
nosy_names = ['r.david.murray', 'ysj.ray', 'bolt']
pr_nums = []
priority = 'normal'
resolution = 'not a bug'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue8762'
versions = ['Python 2.5']

@bolt
Copy link
Mannequin Author

bolt mannequin commented May 19, 2010

After debugging for a while I finally released that I stumbled across a Python bug (at least I believe it is). Here is a proof of concept that produces the issue:

!/usr/bin/python

class blah:

    def __init__(self, items=[]):
        self.items = items

a = blah()
b = blah()

a.items.append("apples")
b.items.append("oranges")

print a.items
print b.items
print id(a.items)
print id(b.items)

and here is the output when the program is run:

root@x:# python pythonbug.py
['apples', 'oranges']
['apples', 'oranges']
135923500
135923500
root@x:
#

as you can see the 'items' reference is the same for both objects even though they are different objects. I checked the manual and I couldn't find anything explaining such behavior. Can this possibly be correct?

My python info:

Python 2.5.2 (r252:60911, Jan 20 2010, 21:48:48)

@bolt bolt mannequin added the type-bug An unexpected behavior, bug, or error label May 19, 2010
@bitdancer
Copy link
Member

This is not a bug, it's how Python works. Default values are computed at function definition time, so there's only one list across all the function invocations.

@ysjray
Copy link
Mannequin

ysjray mannequin commented May 19, 2010

Here is the explanation from Python Language Reference 7.6: Function Definitions
"""
When one or more top-level parameters have the form parameter = expression, the function is said to have default parameter values.'' For a parameter with a default value, the corresponding argument may be omitted from a call, in which case the parameter's default value is substituted. If a parameter has a default value, all following parameters must also have a default value -- this is a syntactic restriction that is not expressed by the grammar. Default parameter values are evaluated when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that that same pre-computed'' value is used for each call. This is especially important to understand when a default parameter is a mutable object, such as a list or a dictionary: if the function modifies the object (e.g. by appending an item to a list), the default value is in effect modified. This is generally not what was intended. A way around this is to use None as the default, and explicitly test for it in the body of the function, e.g.:

def whats_on_the_telly(penguin=None):
    if penguin is None:
        penguin = []
    penguin.append("property of the zoo")
    return penguin
"""

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

1 participant