I am creating a simple GUI program to manage priorities.
I have successfully managed to add functionality to add an item to the listbox. Now I want to add the item to the something what is known as List<> in C#. Does such a thing exist in Python?
For instance, in C#, to add an item to the listview I would first create:
List<Priority> priorities = new List<Priority>();
…and then create the following method:
void Add() { if (listView1.SelectedItems.Count > 0) { MessageBox.Show("Please make sure you have no priorities selected!", "Notification", MessageBoxButtons.OK, MessageBoxIcon.Information); } else if (txt_Priority.ReadOnly == true) { MessageBox.Show("Please make sure you refresh fields first!", "Notification", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { if ((txt_Priority.Text.Trim().Length == 0)) { MessageBox.Show("Please enter the word!", "Notification", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { Priority p = new Priority(); p.Subject = txt_Priority.Text; if (priorities.Find(x => x.Subject == p.Subject) == null) { priorities.Add(p); listView1.Items.Add(p.Subject); } else { MessageBox.Show("That priority already exists in your program!"); } ClearAll(); Sync(); Count(); } } SaveAll(); }
Advertisement
Answer
Type hints
Since Python 3.5, it’s possible to add type hints. Coupled with dataclasses (Python 3.7+), and generic collections (Python 3.9+), you can write:
from dataclasses import dataclass @dataclass class Priority: """Basic example class""" name: str level: int = 1 foo = Priority("foo") bar = Priority("bar", 2) priorities: list[Priority] = [foo, bar] print(priorities) # [Priority(name='foo', level=1), Priority(name='bar', level=2)] print(sorted(priorities, key= lambda p: p.name)) # [Priority(name='bar', level=2), Priority(name='foo', level=1)] baz = "Not a priority" priorities.append(baz) # <- Your IDE will probably complain print(priorities) # [Priority(name='foo', level=1), Priority(name='bar', level=2), 'Not a priority']
In Python 3.5, the code would look like:
from typing import List class Priority: """Basic example class""" def __init__(self, name: str, level: int = 1): self.name = name self.level = level def __str__(self): return '%s (%d)' % (self.name, self.level) def __repr__(self): return str(self) foo = Priority("foo") bar = Priority("bar", 2) priorities: List[Priority] = [foo, bar] print(priorities) # [foo (1), bar (2)] print(sorted(priorities, key=lambda p: p.name)) # [bar (2), foo (1)] baz = "Not a priority" priorities.append(baz) # <- Your IDE will probably complain print(priorities) # [foo (1), bar (2), 'Not a priority']
Note that type hints are optional, and the above code will run fine, even if there’s a type mismatch when appending baz
.
You can explicitly check for errors with mypy
:
❯ mypy priorities.py priorities.py:22: error: Argument 1 to "append" of "list" has incompatible type "str"; expected "Priority" Found 1 error in 1 file (checked 1 source file)
Dynamic language
Even if it now has type hints, Python stays dynamic, and type hints are completely optional:
>>> my_generic_list = [] >>> my_generic_list.append(3) >>> my_generic_list.append("string") >>> my_generic_list.append(['another list']) >>> my_generic_list [3, 'string', ['another list']]
You don’t have to define anything before appending any object to an existing list.
Python uses duck-typing. If you iterate on a list and call a method on each one of the elements, you need to make sure that the elements understand the method.
So if you want the equivalent of :
List<Priority> priorities
you just need to initialize a list and make sure you only add Priority
instances to it. That’s it!