OVH Cloud OVH Cloud

[LONG] Questions de newbie...

19 réponses
Avatar
Gilles CN
Bonjour,

<3615 Ma_Vie>
Je suis un débutant total concernant le Python. J'ai quelques notions en
programmation mais rien de bien exceptionnel (la bonne vieille époque du
BASIC sur mon CPC464 est révolue :) ). Occasionnellement, il m'arrive de
faire quelques petits script en bash ou en PHP mais rien de jamais
exceptionnel.

Bref, tout ça pour dire qu'en voulant me lancer dans le Python, je
découvre deux choses:
1) Un nouveau langage de programmation
2) La programmation objets.

Concernant ce deuxième point, je dois reconnaitre que, même si Python
semble rendre la tâche plutot aisée, certains concept de l'OOP
m'échappent complètement.

Je me lance actuellement dans le développement d'un tout petit script
permettant de lancer 'mencoder' afin d'enregistrer la TV via ma carte tuner.

Pour cela, j'ai un fichier rc ("parsé" avec ConfigParser) qui contient
les paramètres que je souhaite utiliser et j'utilise optparse afin de
récupérer les arguments passés via la ligne de commande.

Je pense que, pour débuter, ce n'est pas trop simple ni trop compliqué
comme petit projet (j'avais essayé de faire ce machin en bash mais
bonjour la lenteur :s).

Voila plusieurs jours que je parcoure le web et que je m'abreuve de docs
et de tutoriaux divers et variés afin d'essayer de cerner au mieux ce
langage de programmation. J'ai également téléchargé divers programme
rédigés en Python que je décortique afin d'y voler quelques idées, bouts
de code, etc...
</3615 Ma_Vie>

Bref...

Je me retrouve face à un problème que j'ai beaucoup de mal à comprendre.

Plutot que d'entamer un long discours (j'ai deja épuisé mon quota avec
ma longue intro), voici ce que je tape:

[===== Fichier: main.py =====]
#!/usr/bin/env python
from config import Config
from test import Test

Config = Config()
Test = Test()

print Config.VAR
Test.test()
print Config.VAR
==============================

[==== Fichier: config.py ====]
class Config:

def __init__(self):
self.VAR = "Config"
==============================

[===== Fichier: test.py =====]
class Test:

def test(self):
from config import Config
Config = Config()
print Config.VAR
Config.VAR = "Test"
print Config.VAR
==============================

Lorsque je lance ce script j'obtiens:
$ ./main.py
Config
Config
Test
Config

Et là, vous allez me répondre "Ben ouais, c'est normal !!!".
Oui mais pourquoi ? Quelqu'un pourrait-il m'expliquer pourquoi ?

Je pensais que le fait de définir une classe Config permettait de
pouvoir (par exemple) stocker des valeurs pouvant être appelées depuis
n'importe où durant l'exécution du script.

J'imagine qu'utiliser des variables globales est peu recommandé ?

D'ailleurs, je n'ai pas trouvé comment définir des variables globales en
Python. Je suppose que c'est faisable ?! Par exemple, je pense à une
variable 'version' qui serait déclarée en début du script et qui
pourrait être récupérée depuis n'importe où !

Une dernière chose.

N'ayant pas envie de poser une tonne de questions sur ce newsgroups dès
que je me retrouve heurté à un problème minable, j'envisage l'achat d'un
ouvrage sur Python. Un petit tour sur fnac.com et j'ai découvert un
livre intitulé "Python en concentré" de 670 pages.

Est-ce que ce bouquin vaut le coup (51.30€, je veux bien les dépenser
mais seulement si c'est valable). Sinon quel(s) livre(s) pouvez-vous me
recommander ?

Merci d'avoir lu ce message jusqu'ici et merci à ceux qui voudront bien
m'accorder quelques minutes de leur temps pour y répondre.

Gilles C.

9 réponses

1 2
Avatar
Michel Claveau - abstraction méta-galactique non triviale en fuite perpétuelle.
'soir !

Exact ; il s'agit du livre "Python cookbook" disponible sous forme de
fichier d'aide windows.
Ce livre (toujours chez O'reilly) est très intéressant aussi, car il donne
beaucoup d'exemples (de recettes/ou trucs) très formateur.

@-salutations
--
Michel Claveau
Avatar
huron benoit
Salut,

Je prépare une réponse consistante à votre problème avec l'OOP (mais je
pense que je posterai ça ce week-end).

En attendant sur la bibliographie :

- Python in a nutshell est un livre excellent. C'est celui que vous
devez acheter.
- Armé de ce premier livre, vous aurez accès au meilleur livre à ce jour
sur Python. Text processing in Python (c'est un livre hétérodoxe,
attention). Il est en accès libre ici :
http://gnosis.cx/TPiP/
Ce livre m'a appris tout ce que je sais d'intéressant sur la programmation.

Parler anglais est une bonne chose mais parler russe est encore plus
intéressant (les russes n'ont pas d'argent à gaspiller).

1 - Rendez-vous sur ce site
http://lib.canmos.ru/search.php

2- Entrez "python" sur la premiere ligne blanche que vous voyez.
3- validez en appuyant sur "Nauti" (à peu près, ça veut dire "trouver").
4- pour le reste je vous fais confiance.
Avatar
Gilles CN
huron benoit wrote:
Salut,

Je prépare une réponse consistante à votre problème avec l'OOP (mais je
pense que je posterai ça ce week-end).

En attendant sur la bibliographie :

- Python in a nutshell est un livre excellent. C'est celui que vous
devez acheter.
- Armé de ce premier livre, vous aurez accès au meilleur livre à ce jour
sur Python. Text processing in Python (c'est un livre hétérodoxe,
attention). Il est en accès libre ici :
http://gnosis.cx/TPiP/
Ce livre m'a appris tout ce que je sais d'intéressant sur la programmation.

Hop ! Bookmark... :)



Parler anglais est une bonne chose mais parler russe est encore plus
intéressant (les russes n'ont pas d'argent à gaspiller).

1 - Rendez-vous sur ce site
http://lib.canmos.ru/search.php

2- Entrez "python" sur la premiere ligne blanche que vous voyez.
3- validez en appuyant sur "Nauti" (à peu près, ça veut dire "trouver").
4- pour le reste je vous fais confiance.

Impressionant ! Je savais bien que j'aurais dû apprendre le Russe ;)


Merci infiniment pour ces quelques renseignements et je renouvelle
également ces remerciements pour toutes les personnes qui m'ont répondues.

Gilles.

Avatar
Michel Claveau - abstraction méta-galactique non triviale en fuite perpétuelle.
Bonjour !

Les russes n'ont peut-être pas d'argent à gaspiller, mais, pourtant, Moscou
est la première ville d'Europe, en terme d'achat de Mercedes-Benz.
De plus, dans cette même ville, s'ouvrent, tous les jours, de nouveaux
casinos ou espaces de jeux d'argent...

Mais quel beau pays, et quels gens sympathiques.

@-salutations
--
Michel Claveau
Avatar
Christophe M
Gilles CN wrote:

Si tu supporte l'anglais, et si tu développes sous Windows, je te
conseille
très fortement "Python programming on win32", qui donnent plein de trucs
extraordinaires (pour windows).

Enfin, si l'anglais ne te donne pas de boutons, regarde ce lien :
http://miaw.tcom.ou.edu/~dody/aspnpython-2004-08-26.chm

Je "développe" principalement sous (et pour) Linux et je n'arrive

malheureusement pas à consulter ce lien (.chm ce sont les fichiers
d'aide de Windows si ma mémoire ne me fait pas défaut ?!). Je
regarderais ça quand j'aurais l'occasion de mettre la main sur une
machine Windows.



@+


Encore merci.

Gilles.


Allons, il existe des lecteurs .chm sous linux aussi ;-)
au hasard : http://www.herdsoft.com/linux/themen/chmviewer.html

Sinon, ce n'est qu'une compilation des pages du python cookbook visible
ici : http://aspn.activestate.com/ASPN/Cookbook/Python

Pour débutant encore, personne n'a mensionné "Apprendre à programmer
avec Python" ?
http://www.ulg.ac.be/cifen/inforef/swi/python.htm

Très bon pour commencer, et puis si comme tu le dis tu es déjà bon en
développement, ça se lit très vite, et ça n'est donc pas une perte de temps.


Avatar
Tibi
On Thu, 26 Aug 2004 18:31:27 +0200, Florence Leroy
wrote:

Ce livre s'adresse :


Merci Florence pour ces précisions.

Et 10 points de plus pour O'Reilly dans mon estime !
Si vous connaissez d'autres éditeurs qui répondent à leurs lecteurs
potentiels sur les newsgroups faites moi signe :)

Avatar
Tibi
On Thu, 26 Aug 2004 23:01:14 +0000, huron benoit
wrote:

Parler anglais est une bonne chose mais parler russe est encore plus
intéressant (les russes n'ont pas d'argent à gaspiller).

1 - Rendez-vous sur ce site
http://lib.canmos.ru/search.php


Rassure-moi là t'es pas en train de poster un site russe qui pirate des
livres ?

Avatar
huron benoit
Gilles CN wrote:

Plutot que d'entamer un long discours (j'ai deja épuisé mon quota avec
ma longue intro), voici ce que je tape:

[===== Fichier: main.py =====]
#!/usr/bin/env python
from config import Config
from test import Test

Config = Config()
Test = Test()

print Config.VAR
Test.test()
print Config.VAR
============================= >
[==== Fichier: config.py ====]
class Config:

def __init__(self):
self.VAR = "Config"
============================= >
[===== Fichier: test.py =====]
class Test:

def test(self):
from config import Config
Config = Config()
print Config.VAR
Config.VAR = "Test"
print Config.VAR
============================= >
Lorsque je lance ce script j'obtiens:
$ ./main.py
Config
Config
Test
Config

Et là, vous allez me répondre "Ben ouais, c'est normal !!!".
Oui mais pourquoi ? Quelqu'un pourrait-il m'expliquer pourquoi ?


Il est impossible de comprendre la programmation OOP sans comprendre le
concept de domaine de noms (namespace). Les classes et les instances ne
sont, après tout, que des domaines de noms qui se trouvent être en relation.

-Concept-

Chaque domaine est une sorte de tableau (pour Python il a la forme d'un
dictionnaire) dont chaque entrée est une relation nom-objet.
Par exemple il y a le domaine local (qui contient, par exemple, les noms
assignés à l'intérieur d'une fonction particulière), le domaine
global(noms assignés
au niveau du module, noms déclarés globaux par le built-in global), le
domaine built-in (qui contient les noms prédéfinis par Python).
Ce qu'il est important de comprendre est qu'il n'y a aucune relation
entre les noms de ces différents domaines. Exemple

x = 4 # x est dans le domaine global
def test () :
x= 10 # ce x là est dans le domaine local à la fonction
# test. Il n'a pas de rapport avec le x global
print x

test() # 10
print x # 4

-Où ça commence à se compliquer- (tutorial de Guido)

Les domaines sont crées à des moments divers et ont une durée de vie
plus ou moins longue.Le domaine de noms qui contient les built-ins est
créé au lancement de l'interpréteur Python, et n'est jamais effacé. Le
domaine global pour un module est créé quand la définition du module est
chargée; normalement, le domaine de noms des modules vivent jusqu'à la
mort de l'interpréteur. Les instructions exécutées à l'invocation de
l'interpréteur par le niveau supérieur, qu'elles soient lues depuis un
fichier ou entrées de façon interactive, sont considérées comme faisant
partie d'un module appelé __main__, elles ont donc leur propre domaine
de noms global. (En fait, les noms intégrés font aussi partie d'un
module appelé __builtin__.)

(là c'est important) Le domaine de noms local à une fonction est créé
quand celle-ci est appelée et il est effacé quand la fonction se termine
ou déclenche une exception qui n'est pas gérée dans la fonction. (En
fait, oublié décrit mieux ce qui se passe vraiment.)

Une portée (scope) est une région textuelle d'un programme Python dans
laquelle un domaine de noms est directement accessible. ``Directement
accessible'' veut dire qu'une référence non qualifiée à un nom cherchera
ce nom dans cet espace de noms.

-Votre programme maintenant-

Config = Config()
Test = Test()

Lorsqu'on assigne à des noms non qualifiés (pas de la forme objet.nom),
le nom est intégré au domaine de nom de la portée en cours. Ici la
portée est celle du module. Config et Test font donc partie de votre
domaine global.
Autre chose : les instances de classe (comme les classes) ont un domaine
local qui leur est propre. Vous venez donc de créer deux domaines locaux
dont l'un (celui de Config) contient la variable VAR :

print Config.VAR

Vous accédez ici à la variable VAR, qui fait référence à l'objet
"Config", dans le domaine local de l'instance nommé Config (pour cela
vous avez utilisé un nom qualifié).

Test.test()

Vous essayez ici d'accédez à la méthode test() dans le domaine local de
l'instance Test. Python commence par chercher dans ce domaine. Il n'y
trouve pas la méthode test(). Il la cherche alors dans le domaine local
de la classe Test (il sait faire ça car les instances "savent" à quelle
classe elles appartiennent). Il la trouve. Python execute ensuite cette
méthode en passant comme premier argument l'instance Test (ce n'est pas
moi, mais vous qui avez décidé de nommer toutes vos variables à
l'identique. Cela ne gêne en aucune façon Python, juste nous.)

def test(self):
from config import Config
Config = Config()
print Config.VAR
Config.VAR = "Test"
print Config.VAR


Python est donc maintenant dans le domaine local à la méthode test
(méthode elle-même dans le domaine local de la classe Test). Il y
importe la classe Config. Puis execute :

Config = Config()

Cela a pour effet de créer une instance (un domaine de nom) de la classe
Config que vous liez au nom Config.Ce nom -Config- fait partie du
domaine local à votre fonction. Il n'a pas de rapport avec le Config de
votre domaine global (un assignement à un nom non qualifié se fait
toujours dans la portée en cours).

print Config.VAR

Vous commencez à comprendre que cela affiche "Config", car toutes les
instances de la classe Config sont initialisées de la même façon. Mais
lorsque vous changez la valeur de Config.VAR en Test cela n'affecte
évidemment que le domaine de nom de l'instance Config créee dans le
domaine local à votre fonction. Vous n'avez pas accès au domaine de nom
de Config crée dans le domaine global (celui du début).

print Config.VAR #imprime Test

Lorsque l'exécution de la fonction termine, selon les règles exposées
dans l'extrait du tutorial de Guido, son domaine de nom est effacé. Cela
efface les noms à peine crées : Config (la classe), Config (le nom
d'instance). Que deviennent les objets dont les noms sont effacés ? Ils
disparaissent. L'instance à laqelle faisait référence Config disparaît,
disparaît avec elle la variable VAR et donc (vous me suivez?) l'objet
"Test".

Votre programme reprend ensuite :

print Config.VAR


Vous êtes de nouveau dans le domaine global. De là, vous accédez à la
variable VAR du domaine de nom de Config (le Config de la portée
actuelle, c'est-à-dire du domaine global de votre module main). Vous
n'avez jamais touché à ce domaine de nom depuis le début de votre
programme, vous ne l'avez jamais modifié (et son double maléfique et
local a été détruit avec la fin de la méthode test() !). Python imprime
donc gentiment et patiemment ce qu'il vous avez déjà imprimé, à savoir
l'objet "Config".

$ ./main.py
Config
Config
Test
Config


Vous comprenez maintenant ce résultat.

Votre question maintenant. Si chaque assignation se fait forcément dans
la portée en cours, comment, à l'intérieur d'un domaine de noms local,
avoir accès à un nom (une variable) du domaine global pour pouvoir y
assigner un nouvel objet ?
Réponse. Le built-in global.
Celui-ci déclare la variable qui le suit comme faisant partie du domaine
global (voir doc en ligne, tutorial, Learning Python, et Text processing
in Python pour explications et exemples. Je ne garantis pas l'exactitude
technique de tout ce que je viens de dire).

Benoît.

Avatar
Gilles CN
Christophe M wrote:
Allons, il existe des lecteurs .chm sous linux aussi ;-)
au hasard : http://www.herdsoft.com/linux/themen/chmviewer.html

Effectivement, j'ai trouvé "xchm" fournit dans les contribs de ma

distrib'. Ca semble être largement suffisant pour consulter ces fichiers :).


Sinon, ce n'est qu'une compilation des pages du python cookbook visible
ici : http://aspn.activestate.com/ASPN/Cookbook/Python

Pour débutant encore, personne n'a mensionné "Apprendre à programmer
avec Python" ?
http://www.ulg.ac.be/cifen/inforef/swi/python.htm

Très bon pour commencer, et puis si comme tu le dis tu es déjà bon en
développement, ça se lit très vite, et ça n'est donc pas une perte de
temps.

"Bon en développement"... Je n'irai pas jusqu'à dire cela. Mais c'est

vrai que je possède quelques compétences (vraiment basiques) en
programmation mais rien de bien exceptionnel.

Cdt,
Gilles.

1 2