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

lambda function in loop #71860

Closed
Thaloss66 mannequin opened this issue Aug 3, 2016 · 3 comments
Closed

lambda function in loop #71860

Thaloss66 mannequin opened this issue Aug 3, 2016 · 3 comments
Labels
type-bug An unexpected behavior, bug, or error

Comments

@Thaloss66
Copy link
Mannequin

Thaloss66 mannequin commented Aug 3, 2016

BPO 27673
Nosy @Vgr255
Files
  • lambda-prob.pyw: Demo of issue
  • 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 2016-08-03.11:45:29.724>
    created_at = <Date 2016-08-03.11:39:41.013>
    labels = ['type-bug', 'invalid']
    title = 'lambda function in loop'
    updated_at = <Date 2016-08-03.12:30:40.085>
    user = 'https://bugs.python.org/Thaloss66'

    bugs.python.org fields:

    activity = <Date 2016-08-03.12:30:40.085>
    actor = 'Thaloss66'
    assignee = 'none'
    closed = True
    closed_date = <Date 2016-08-03.11:45:29.724>
    closer = 'abarry'
    components = []
    creation = <Date 2016-08-03.11:39:41.013>
    creator = 'Thaloss66'
    dependencies = []
    files = ['43989']
    hgrepos = []
    issue_num = 27673
    keywords = []
    message_count = 3.0
    messages = ['271897', '271899', '271902']
    nosy_count = 2.0
    nosy_names = ['abarry', 'Thaloss66']
    pr_nums = []
    priority = 'normal'
    resolution = 'not a bug'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue27673'
    versions = ['Python 3.5']

    @Thaloss66
    Copy link
    Mannequin Author

    Thaloss66 mannequin commented Aug 3, 2016

    Trying to build tkinter menu dynamically by reading an ini file (configparser) I detect an issue with the lambda function used inside a loop.
    If the loop variable is used as option in the lambda function, the lambda is not place in time using the current value, all functions are created when leaving the calling function using the last value of the loop variable.
    There is a simple workaround, just use a separate function to add the menu-item.
    The attached demo shows both, the "Working" menu which was created by a function and does what was expected and the "Failure" menu which was created inside the loop itself and doesn't do what was expected.
    Since the problem is not bound to configparser I used a simple loop walking through a list of menu item names to simulate the reasing of an ini file. Inside the loop a menu item with the name is appende to the Failure menu calling lambda:cmd(name) as command. Also a function is called uding the name as parameter wich appends a Menu item to the Working menu using the identic options as for Failure menu.
    When the loop is finidhed the value of teh loop variable is set to "senseless" which should have no effect.
    The function cmd(param) just appends a string including the param value to the output.
    if the script is started the menus ar built and look identical but if you click on a Working menu item the name of the item is printed. if you click on the Failure menu item "senseless" is printed for each item which is the value I set after the loop.

    From my point of view all lambda commands are build when the calling function is left using the value of the variable at this time. this lead in the demo attached to identic function calls for the Failure menu. For the working menu a separate function is called and the lambda is build at the end of this function which leads to the expected behaviour.

    I'm running Python 3.5.2 (v3.5.2:4def2a2901a5) 64 Bit on Windows-10 Pro 64

    @Thaloss66 Thaloss66 mannequin added topic-tkinter type-bug An unexpected behavior, bug, or error labels Aug 3, 2016
    @Vgr255
    Copy link
    Mannequin

    Vgr255 mannequin commented Aug 3, 2016

    This is due to how closures work in Python: they only look up the value of the variable when the function is executed, not when it is created.

    See the FAQ for more information and how to work around this: https://docs.python.org/3/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result

    @Vgr255 Vgr255 mannequin removed the topic-tkinter label Aug 3, 2016
    @Vgr255 Vgr255 mannequin closed this as completed Aug 3, 2016
    @Vgr255 Vgr255 mannequin added the invalid label Aug 3, 2016
    @Thaloss66
    Copy link
    Mannequin Author

    Thaloss66 mannequin commented Aug 3, 2016

    @emanuel Barry
    thanks for clarification, I didn't find this when I was searching for.

    regards

    Stefan

    @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

    0 participants