Python Forum
Whys is asterisk and random variable necessary in these functions?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Whys is asterisk and random variable necessary in these functions?
#1
In this basic Python Tkinter code, I'm trying to bind certain functions to trigger upon either a UI button press or a keyboard key press.

import tkinter as tk from tkinter import ttk main_window = tk.Tk() main_window.title('Test UI') # Change text with "Enter" then flush def changeTextEnter(): text_label.configure(text=entry_bar.get()) entry_bar.delete(0, tk.END) # Close program key function def quitApp(): main_window.destroy() # Enter Button enter_button = ttk.Button(text='Enter', command=changeTextEnter) enter_button.grid(row=0, column=0) # Entry bar entry_bar = ttk.Entry(width=30) entry_bar.grid(row=0, column=1) # Quit Button quit_button = ttk.Button(text='Quit', command=main_window.destroy) quit_button.grid(row=0, column=2) # Text label text_label = ttk.Label(text='TEST TEXT GOES HERE') text_label.grid(row=1, column=0, columnspan=2) # Bind enter key main_window.bind('<Return>', changeTextEnter) # Bind quit key main_window.bind('<Escape>', quitApp) main_window.mainloop()
After a while of trial and error, it seems to work the way I want if I add an *randomVariable in the declarations of def changeTextEnter(*randomVariable): and def quitApp(*randomVariable):
I get that one asterisk lets the function take an unknown number of arguments, and a double asterisk acts as a dictionary with key values.

My questions are:
  1. Why do I need a parameter in those functions at all?
  2. How does the variable *randomVariable get used, since it seems like I'm not actually using/ assigning anything to randomVariable anywhere within the function.
  3. Why does the function not work as intended without the asterisk before the variable?
Reply
#2
When you bind the callback to a key, it receives a KeyPress event parameter every time the key is pressed. On the other hand, a function bound to a Button does not receive a parameter when the button is pressed. So if you want to bind the callbacks both to a key and to a Button, you need to give them a variable number of arguments. Try adding a print() in the functions to see what it does
# Change text with "Enter" then flush def changeTextEnter(*args): print('changeTextEnter:', args) text_label.configure(text=entry_bar.get()) entry_bar.delete(0, tk.END) # Close program key function def quitApp(*args): print('quit:', args) main_window.destroy()
Output:
changeTextEnter: (<KeyPress event keysym=Return keycode=36 char='\r' x=89 y=14>,) changeTextEnter: () quit: (<KeyPress event keysym=Escape keycode=9 char='\x1b' x=181 y=14>,)
rrowhe4d likes this post
Reply
#3
The function signature is misleading. Don't use the asterisk, if you expect a static number of arguments. The callback sends one argument, which is the event itself. You should change the callbacks (example taken form Gribouillis).

# Change text with "Enter" then flush def changeTextEnter(event): print('changeTextEnter:', event) text_label.configure(text=entry_bar.get()) entry_bar.delete(0, tk.END) # Close program key function def quitApp(event): print('quit:', event) main_window.destroy()
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#4
You should read the documentation. This describes what arguments are passed to the bound event callback.

https://docs.python.org/3/library/tkinte...d-events-1

In your example you are binding a key code (<Return>, <Escape>), so the argument passed to your functions is an event that contains the key that was pressed.

This is a little program that displays the event in an Entry widget. You can select the entry and type and it works like normal, but it you press <Return> or <Escape> an text is replaced by the event info.
import tkinter as tk class MainWindow(tk.Tk): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.title("Test UI") self.bind("<Return>", self.keypress) self.bind("<Escape>", self.keypress) self.text = tk.StringVar(self, "") tk.Entry(self, textvariable=self.text, width=80).pack(padx=20, pady=20) def keypress(self, event): self.text.set(str(event)) MainWindow().mainloop()
If you don't use the event you can ignore it. The linter in my IDE does not like functions arguments that aren't used in the function, so I use a place holder instead of an argument.
 def keypress(self, _): self.text.set("something happened")
The "_" in the function declaration tells the reader that one argument is passed, but not used by the function. Unfortunately you can only use one "_". If there are multiple arguments to ignore I might do this:
def keypress(self, *_):
But I cannot do this:
def keypress(self, *_, **_):
I can also use a lambda expressing to remove or replace the event argument.
self.bind("<Return>", lambda event:self.keypress("Return was pressed") self.bind("<Escape>", lambda event:self.keypress("Escape was pressed") def keypress(self, msg): self.text.set(msg)
Here the lambda expression consumes the "event" argument and passes along a different argument.
Reply
#5
(Aug-04-2022, 07:10 PM)deanhystad Wrote: But I cannot do this:

1 def keypress(self, *_, **_):

You should read the error messages:
Error:
SyntaxError: duplicate argument '_' in function definition
Fix:

class Test: def keypress(self, *args, **kwargs): ...
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#6
You could also do
def changeTextEnter(event=None): ...
This allows zero or one argument.
buran likes this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Functions: why use a variable "display" in a UDF as a Boolean MMartin71 3 1,077 May-26-2025, 05:55 AM
Last Post: DeaD_EyE
  How to Print a Pyramid Asterisk Pattern in Python? williamclark 0 1,519 Mar-24-2025, 10:05 AM
Last Post: williamclark
  Calling functions by making part of their name with variable crouzilles 4 2,616 Nov-02-2023, 12:25 PM
Last Post: noisefloor
  trying to input a variable using random.choice python63 9 6,228 Aug-13-2020, 05:37 PM
Last Post: python63
  Help removing asterisk item in a nested list. bmcguire 3 4,342 Apr-06-2020, 02:35 PM
Last Post: snippsat
  append one random intergar variable Coastal 5 5,545 Dec-18-2019, 09:18 PM
Last Post: ichabod801
  random variable function? Novice_fanatic 4 4,145 Oct-08-2019, 01:22 PM
Last Post: jefsummers
  Guidance in Creating random output for a variable. Livne_ye 1 3,420 May-04-2019, 01:18 PM
Last Post: Yoriz
  How do you make functions that take a variable that is not defined? magic 6 6,925 Sep-24-2018, 01:30 PM
Last Post: gruntfutuk
  multiprocess passing multiple arguments double asterisk pic8690 1 6,883 Oct-23-2016, 08:51 AM
Last Post: Skaperen

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020
This forum uses Lukasz Tkacz MyBB addons.
Forum use Krzysztof "Supryk" Supryczynski addons.