Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Objet ou dictionnaire ?

7 réponses
Avatar
NicolasP
Bonjour,

J'aimerais créer l'équivalent C d'une liste de structures.
J'hésite entre 2 implémentations :

La première :
class Task (object) :
def __init__ (self) :
self.Time = None
self.FunctionToCall = None

class Scheduler (object) :
_Tasks = []

def __init__ (self) :
pass

def AddTask (self, Time, FunctionToCall) :
t = Task()
t.Time = Time
t.FunctionToCall = FunctionToCall
Scheduler._Tasks.append(t)

def Removetask (self) :
# TODO
pass

def RunTasks (self)
for t in Scheduler._Tasks :
# TODO
pass

La deuxième :
class Scheduler (object) :
_Tasks = []

def __init__ (self) :
pass

def AddTask (self, Time, FunctionToCall) :
t = {}
t["Time"] = Time
t["FunctionToCall"] = FunctionToCall
Scheduler._Tasks.append(t)

def Removetask (self) :
# TODO
pass

def RunTasks (self)
for t in Scheduler._Tasks :
# TODO
pass

La première solution me parait plus pythonesque mais est-ce la meilleure ?

Nicolas

7 réponses

Avatar
Bruno Desthuilliers
Bonjour,

J'aimerais créer l'équivalent C d'une liste de structures.
J'hésite entre 2 implémentations :

La première :
class Task (object) :
def __init__ (self) :
self.Time = None
self.FunctionToCall = None



Si tu veux vraiment faire "pythonesque", utilise l'initialisateur
correctement, et respecte le pep08 (conventions de nommage):

class Task(object):
def __init__(self, time, action):
self.time = time
self.action = action


class Scheduler (object) :
_Tasks = []


_tasks = []

def __init__ (self) :
pass

def AddTask (self, Time, FunctionToCall) :
t = Task()
t.Time = Time
t.FunctionToCall = FunctionToCall
Scheduler._Tasks.append(t)


def add_task(self, time, action):
self._tasks.append(Task(time, action))

(etc)

La deuxième :
class Scheduler (object) :
_Tasks = []

def __init__ (self) :
pass

def AddTask (self, Time, FunctionToCall) :
t = {}
t["Time"] = Time
t["FunctionToCall"] = FunctionToCall
Scheduler._Tasks.append(t)

(snip)


La première solution me parait plus pythonesque


Pas en l'état, puisque pour le moment elle n'apporte rien par rapport à
la seconde.

Par contre:

mais est-ce la meilleure ?


Ce serait probablement la meilleure si tu ajoutais quelques
fonctionnalités utiles à l'object Task - par exemple, la gestion de
l'état (à executer, en cours, etc...) et des fonctions de comparaison
permettant de repérer deux tâches identiques (time + action ? attention,
si action est une méthode d'un autre objet, comparer sur action.im_func
+ action.im_self), et/ou de les ordonnancer (comparaison sur task.time ?)...


Mes deux centimes...

Avatar
NicolasP

Si tu veux vraiment faire "pythonesque", utilise l'initialisateur
correctement, et respecte le pep08 (conventions de nommage):
Pour le nommage, j'essaye mais, souvent, mes habitudes reprennent le dessus...



class Task(object):
def __init__(self, time, action):
self.time = time
self.action = action

D'habitude je le fais comme ça.

Promis, je ne le referai pas.

La première solution me parait plus pythonesque


Pas en l'état, puisque pour le moment elle n'apporte rien par rapport à
la seconde.

Et dans mon cas réel, il n'y a rien à ajouter. Du moins pour l'instant.


Ce serait probablement la meilleure si tu ajoutais quelques
fonctionnalités utiles à l'object Task - par exemple, la gestion de
l'état (à executer, en cours, etc...) et des fonctions de comparaison
permettant de repérer deux tâches identiques (time + action ? attention,
si action est une méthode d'un autre objet, comparer sur action.im_func
+ action.im_self), et/ou de les ordonnancer (comparaison sur task.time
?)...
L'objet est évidemment plus "ouvert" à des modifications ultérieures.


Est-ce que task["Time"] est plus long à manupiler que task.time ?


Nicolas


Avatar
Bruno Desthuilliers

Si tu veux vraiment faire "pythonesque", utilise l'initialisateur
correctement, et respecte le pep08 (conventions de nommage):
Pour le nommage, j'essaye mais, souvent, mes habitudes reprennent le

dessus...


class Task(object):
def __init__(self, time, action):
self.time = time
self.action = action

D'habitude je le fais comme ça. Promis, je ne le referai pas.


La première solution me parait plus pythonesque


Pas en l'état, puisque pour le moment elle n'apporte rien par rapport
à la seconde.

Et dans mon cas réel, il n'y a rien à ajouter. Du moins pour l'instant.



Si ton cas réel est un scheduler, vu le bordel que ça peux devenir, il y
a des chances que tu ais très vite des choses à ajouter. Mais bon, en
soi, il est plus pythonesque d'utiliser la solution la plus simple qui
ait une chance de faire l'affaire. Donc rien ne t'empêche de commencer
par une liste de dicts, et de passer à une classe spécifique par la
suite. Si tu a un bon éditeur de code, ça devrait pas être trop méchant...

Ce serait probablement la meilleure si tu ajoutais quelques
fonctionnalités utiles à l'object Task - par exemple, la gestion de
l'état (à executer, en cours, etc...) et des fonctions de comparaison
permettant de repérer deux tâches identiques (time + action ?
attention, si action est une méthode d'un autre objet, comparer sur
action.im_func + action.im_self), et/ou de les ordonnancer
(comparaison sur task.time ?)...
L'objet est évidemment plus "ouvert" à des modifications ultérieures.



En partie, oui. Surtout, il est capable de gérer tout seul son état, ce
qui est quand même un des buts de l'OO !-)

Est-ce que task["Time"] est plus long à manupiler que task.time ?


Théoriquement non - au contraire (accès direct vs règles de lookup).

Ah oui, au fait: tu peux créer ton dict et le peupler en une seule ligne:

def add_task (self, time, action) :
self._Tasks.append(dict(time=time, action¬tion))

Mes deux centimes...



Avatar
NicolasP
L'objet est évidemment plus "ouvert" à des modifications ultérieures.


En partie, oui. Surtout, il est capable de gérer tout seul son état, ce
qui est quand même un des buts de l'OO !-)
Tout à fait.



Est-ce que task["Time"] est plus long à manupiler que task.time ?


Théoriquement non - au contraire (accès direct vs règles de lookup).

ok


Ah oui, au fait: tu peux créer ton dict et le peupler en une seule ligne:

def add_task (self, time, action) :
self._Tasks.append(dict(time=time, action¬tion))

Dans mon utilisation réelle, j'ai plus de paramètres. Comme j'aime écrire du code lisible, je décompose en plusieurs lignes. C'est aussi une habitude qui vient du C.


Merci

Nicolas


Avatar
Bruno Desthuilliers
(snip)
Ah oui, au fait: tu peux créer ton dict et le peupler en une seule ligne:

def add_task (self, time, action) :
self._Tasks.append(dict(time=time, action¬tion))

Dans mon utilisation réelle, j'ai plus de paramètres. Comme j'aime

écrire du code lisible, je décompose en plusieurs lignes.


def add_task (self, time, action, toto, tata, tutu, titi) :
task = dict(
time=time,
action¬tion,
toto=toto,
tata=tata,
titi=titi,
tutu=tutu
)
self._Tasks.append(task)


Avatar
NicolasP

def add_task (self, time, action, toto, tata, tutu, titi) :
task = dict(
time=time,
action¬tion,
toto=toto,
tata=tata,
titi=titi,
tutu=tutu
)
self._Tasks.append(task)


Oui bien sûr. Mais j'aime moins.

Avatar
Bruno Desthuilliers

def add_task (self, time, action, toto, tata, tutu, titi) :
task = dict(
time=time,
action¬tion,
toto=toto,
tata=tata,
titi=titi,
tutu=tutu
)
self._Tasks.append(task)


Oui bien sûr. Mais j'aime moins.


Alors je n'ai rien à ajouter...