Bonjour, j'essaye d'apprendre les classes en python. J'aurais besoins de faire quelque chose de ce genre et j'aimerais savoir si c'est possible, je n'ai rien trouvé sur internet. Merci beaucoup de votre aide ! (:



class playerscraping:

    def function(self, username):
        return username + " !"

    def __init__(self, username):
        self.username = function(username)



( ce que je voulais faire était dans la fonction __init__ définir la valeur d'une variable comme le résultat d'une autre fonction ( dans ce cas là, "function()" )
Modérateur
Et l'eau vzytoi,

ton code n'a pas de sens. Au constructeur tu passes le param username. Je t'invite à lire ceci :

class Playerscraping:
    def __init__(self, username):
        self.username = username
    
    @property
    def username(self):
        return self.__username

    @username.setter
    def username(self, username):
        if not isinstance(username, str):
            raise ValueError('must be string arguments')
        self.__username = username

    def __str__(self):
        return f"{self.username} !"


if __name__ == '__main__':
    vzytoi = Playerscraping('vzytoi')
    print(vzytoi)


ps :
- une class (et non pas une fonction de première class) doit être nommée avec une majuscule
- une méthode doit être nommée en minuscule et si cette dernière nécessite plusieurs mots, ça doit être séparé par des caractères underscores/soulignés (ex : do_something)
- il est préférable d'utiliser les docstings. Pour le coup, je ne l'ai pas fait puisque je ne sais pas où tu veux vraiment en venir avec ta class
- si tu veux aller plus loin dans ton propos (dans ce que tu souhaites faire), peut être qu'un décorateur te rendra la vie plus facile. Tout dépend comment tu orientes ton code
Modifié par niuxe (06 Feb 2021 - 16:07)
Meilleure solution
Merci beaucoup de ta réponse, mais ce que je voulais, c'est que lorsque je fais
 print(vzytoi.__dict__) 

il puisse me retourner

{'username': 'vzytoi !'}

C'est pour ça que j'aurais aimé attribuer à ma fonction contructor le résultat de ma fonction
Modifié par vzytoi (06 Feb 2021 - 16:01)
Modérateur
Ah, dès le départ, tu as une méconnaissance de la poo. Et pour le coup, python n'aide pas. Toutes les propriétés d'une class doivent être privées ou protégées d'où l'utilisation d'accesseurs (get/set)

vzytoi.__dict__ est une méthode d'ordre privée et elle te renvoie un dictionnaire des méthodes et attributs disponibles pour l'objet. C'est bien pour déboguer, mais ce n'est pas fait pour un appel extérieur. Pourquoi as tu besoin de ce dict ? tu peux très bien définir une méthode qui te renvoie ce dict. Ou encore mieux, utiliser Collection pour ça dans ton code métier.
Modifié par niuxe (06 Feb 2021 - 16:41)
niuxe a écrit :
Ah, dès le départ, tu as une méconnaissance de la poo. Et pour le coup, python n'aide pas. Toutes les propriétés d'une class doivent être privées ou protégées d'où l'utilisation d'accesseurs (get/set)

vzytoi.__dict__ est une méthode d'ordre privée et elle te renvoie un dictionnaire des méthodes et attributs disponibles pour l'objet. C'est bien pour déboguer, mais ce n'est pas fait pour un appel extérieur. Pourquoi as tu besoin de ce dict ? tu peux très bien définir une méthode qui te renvoie ce dict. Ou encore mieux, utiliser Collection pour ça dans ton code métier.


C'était pour ne pas avoir à coder ce dictionnaire moi même, je voulais écrire tout ça dans un fichier .json
Modérateur
Je viens à l'instant de penser à ceci :

class Playerscraping:
    def __init__(self, username):
        self.username = username
    
    @property
    def username(self):
        return f"{self.__username} !"

    @username.setter
    def username(self, username):
        if not isinstance(username, str):
            raise ValueError('doit être une chaine de caractère')
        self.__username = username

    def get_props(self):
        return dict((name, getattr(self, name)) for name in dir(self) if not name.startswith('_') and not name.startswith('get'))


if __name__ == '__main__':    
    vzytoi = Playerscraping('vzytoi')
    print(vzytoi.get_props())

perso, je ne suis pas fervent du point d'exclamation.
Je viens de regarder cette vidéo : https://www.youtube.com/watch?v=jCzT9XFZ5bw&ab_channel=CoreySchafer sur les décorateurs, je comprends mieux mon erreur mais j'ai quand même une question. Lorsque par exemple dans ton code, tu définie une fonction avec le décorateur @property, il n'y a aucun conflit lorsque l'on essaye de l'appeler?
Si je fais print(x.username), il pourrait me retourner la fonction le self.username de la fonction __init__ mais il pourrait aussi le retourner la fonction avec le décorateur @proerty... J'espère avoir été assez compréhensible (:
PS ( désolé de t'harceler avec mes question ... ) : est-il possible d'importer un module au sein d'une classe sachant que toutes mes fonction l'utilisent donc je voudrais pas l'importer au début de chaque fonction
Modifié par vzytoi (06 Feb 2021 - 17:50)
Modérateur
ah oui tu me harcèles et de ce fait je vais demander à un modérateur de te ban. Smiley lol

Je te conseille de lire ce livre : La programmation orientée objet

tu apprendras mieux le ce concept/cette philosophie de programmation.

Le souci avec Python, les atrtibuts sont publics. Il y a quelques manières de rendre ça privée. Ce que j'ai écrit est une manière de rendre l'attribut protected/private.

username est public mais en sous couche, tu renseignes l'attribut privé __username. Comme tu peux le constater il y a un controle dessus :

...
@username.setter
    def username(self, username):
        if not isinstance(username, str):
            raise ValueError('doit être une chaine de caractère')
        self.__username = username


Le décorateur, c'est en fait un pattern bien connu en poo. En Python, tu as 2 manières d'implémenter celui-ci. Il y a la manière simple comme dans toute poo d'un langage (ex : php) et puis l'écriture pythonique (plus sexy)

En Python tout est strictement objet. CJe ne suis pas sûr que tu aies besoin de déclarer une class sous peine de réinventer la roue.

En repensant à ton sujet, une variante de ce que tu cherches à faire Smiley cligne


class Playerscraping:
    def __init__(self, username):
        self.username = username
    
    @property
    def username(self):
        return f"{self.__username} !"

    @username.setter
    def username(self, username):
        if not isinstance(username, str):
            raise ValueError('doit être une chaine de caractère')
        self.__username = username

    def __call__(self):
        return dict((name, getattr(self, name)) for name in dir(self) if not name.startswith('_') and not name.startswith('get'))


if __name__ == '__main__':    
    vzytoi = Playerscraping('vzytoi')
    print(vzytoi())

Modifié par niuxe (06 Feb 2021 - 18:20)
Modérateur
vzytoi a écrit :
est-il possible d'importer un module au sein d'une classe sachant que toutes mes fonction l'utilisent donc je voudrais pas l'importer au début de chaque fonction


Désolé, j'ai répondu passablement à côté.
Si tu importes en haut du fichier, pas de souci. Mais tu peux faire mieux, hérité. Mais tout dépend du contexte. Hérité c'est bien, composer c'est souvent mieux (tout dépend encore du contexte) ! En python, tu peux faire de l'héritage multiple d'ailleurs. Mais attention, c'est casse-gueule !
Modifié par niuxe (07 Feb 2021 - 16:28)