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!