transformer "self.foobar" en self.foobar

passage d'une string pour selectionner un attribut ou methode qui porte le meme nom sans sans casser la tete à faire un dictionnaire de correspondance

a marqué ce sujet comme résolu.

Salut, si j’ai un grand nombre d’attributs ou de methodes dans un objet, et que je veuille interagir avec à partir d’une string, comment faire ? Par exemple, suite à un input ?

class Truc():

    def __init__(self):

        self.x = 0
        self.y = 0

    def aa(self):
        pass


    def bb(self):
        pass


machin = Truc()


choix = input("quel attribut ou methode ? ")
nouvellevaleur = input("quelle nouvelle valeur cet  attribut ? ")


try:
    choix()
except:
    choix = nouvellevaleur

utiliser

.__name__

ou utiliser ast ?

+0 -0

Salut,

Je ne comprends pas exactement ce que tu cherches à faire (c’est quoi choix() ?), mais il est possible — si je comprends bien le début de ton message — que ce soit la fonction getattr qui réponde à ton problème.

>>> class X:
...     foo = 'bar'
... 
>>> x = X()
>>> getattr(x, 'foo')
'bar'

Tu as aussi setattr pour (re)définir un attribut et delattr pour le supprimer.

class Truc():

    def __init__(self):

        self.x = 0
        self.y = 0

    def aa(self):
        print("bonjour depuis la methode aa")


    def bb(self):
        print("bonjour depuis la methode bb")


machin = Truc()

print(machin)
print(dir(machin))

choix = input("quel attribut ou methode ? ")
nouvellevaleur = input("quelle nouvelle valeur cet  attribut ? ")


try:
    choix() # doit appeller la fonction eponyme si methode (tester iscallable ?) , ex si choix="bb" => machin.bb()
except:
    choix = nouvellevaleur

    setattr(machin, choix, nouvellevaleur) # devrait assigner la nouvelle valeur a l attribut concerne, mais erreur ici on creer un nouvel attribut au lieu de modifier ; si je fais choix = y puis nouvellevaleur = 15 , y restera a zero et ça crée un attribut quinze qui vaut '15' au lieu de machin.y = 15




print(machin.__dict__)
+0 -0

Bonjour,

@buffalo974,

Que veut dire sélectionner un attribut ?

Peux-tu donner un exemple où tu as besoin d’un dictionnaire de correspondance pour "sélectionner un attribut" ?

Qu’est-ce qu’une fonction éponyme, et pourquoi choix qui est une chaîne de caractères, devient tout à coup un objet fonction ?

Si choix devient nouvellevaleur alors on aura setattr(machin, nouvellevaleur, nouvellevaleur) en ligne 30, c’est assez surprenant !

+0 -0

@buffalo974 : je pense que tu te mélange un peu les pinceaux.

class Foo:
    def bar(self):
        print("Foo.bar")

a = Foo()
getattr(a, "bar")()
setattr(a, "baz", 42)
print(a.baz)

Cela dit, toute cette machinerie semble un peu étrange, quel est le but de la manœuvre ?

+0 -0

@fred1559 : éponyme de la string "bb" => appel de la méthode bb. dicp_coresp = {"bb":machin.bb() , "aa":machin.aa()} etc. pour un objets avec pleins d’attributs ou méthodes.Donc chiant à écrire manuellement. Point de départ string car type retourné par input.

@adri1:si il y a beaucoup d' attributs et de méthodes et que le point d’entrée est input, je peux faire un dico {str:call ou set} mais ce dictionnaire est proportionnellement long à écrire manuellement sir l' objet contient de nombreux attributs et méthodes.

+0 -0

Très franchement, tu ne nous aides pas beaucoup à t’aider. Tu n’as pas expliqué clairement ce que tu cherchais à faire, et tu n’as pas expliqué non plus quel est le vrai problème sous-jacent (parce que je parierais surtout sur un problème de conception si tu interagis à coup d'input avec une class)… :-°

Je n’ai honnêtement rien compris à ce que tu essayais de me dire là :

si il y a beaucoup d' attributs et de méthodes et que le point d’entrée est input, je peux faire un dico {str:call ou set} mais ce dictionnaire est proportionnellement long à écrire manuellement sir l' objet contient de nombreux attributs et méthodes.

Ni pourquoi un dictionnaire (avec une définition obscure) apparaît soudainement, ni son rapport avec les attributs et méthodes.

Si tu fais getattr(obj, methode_name)(), tu vas appeler la méthode si elle existe, avoir un AttributeError si il n’y a aucun membre de obj qui s’appelle methode_name, et un TypeError si l’attribut existe mais n’est pas appelable.

+2 -0

Je pense que ton approche n’est pas la bonne : tu ne devrais pas laisser l’utilisateur accéder à ce qu’il veut juste à partir d’une saisie clavier (parce qu’il ne doit pas forcément accéder à tous les détails d’implémentation, entrer un nom qui n’existe pas, mais qu’il doit savoir qu’elles sont ses options etc.).

Je te suggère de plutôt construire une liste d’options automatiquement en "taggant" les attributs et méthodes auxquels tu veux donner accès. Qui plus est, si tu maîtrises la façon dont tu définis les propriétés accessibles, tu peux mieux gérer les mécanismes d’appels

Une approche très grossière :


class Menu:
	_inputs = list()

	@classmethod
	def display(cls):
		print('Choices:')
		for option in cls._inputs:
			print(option.name)

	@classmethod
	def execute(cls, name):
		for option in filter(lambda option: option.name == name, cls._inputs):
			option.call()

	@classmethod
	def registerMethod(cls, func):
		input = MenuAttribute(func.__name__, func)
		cls._inputs.append(input)
		return func

	@classmethod
	def	registerAttribute(cls, object, name, value=None):
		setattr(object, name, value)
		input = MenuAttribute(name, lambda: print(getattr(object, name)))
		cls._inputs.append(input)


class MenuAttribute:
	def __init__(self, name, call):
		self.name = name
		self.call = call


class A:
	def __init__(self):
		Menu.registerAttribute(self, "foo", "this is foo")
		self.bar = "this is bar"
		pass

	@Menu.registerMethod
	def foobar():
		print("In foobar()")



if __name__ == "__main__":
	a = A()

	Menu.display()
	selection = input("> ")
	Menu.execute(selection)
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte