简体   繁体   中英

How to print actual name of variable class type in function?

I'm trying to return variable name, but i keep getting this:

<classes.man.man object at (some numbers (as example:0x03BDCA50))>

Below is my code:

from classes.man import man

def competition(guy1, guy2, counter1=0, counter2=0):
    .......................
    some *ok* manipulations
    .......................
    if counter1>counter2:
        return guy1

bob = man(172, 'green')
bib = man(190, 'brown')
print(competition(bob , bib ))

Epilogue

If anyone want to, explain please what I can write instead of __class__ in example below to get variable name.

def __repr__(self):
        return self.__class__.__name__

Anyway, thank you for all of your support

There are different ways to approach your problem.

The simplest I can fathom is if you can change the class man , make it accept an optional name in its __init__ and store it in the instance. This should look like this:

class man:
    def __init__(number, color, name="John Doe"):
        self.name = name
        # rest of your code here

That way in your function you could just do with:

    return guy1.name

Additionnally, if you want to go an extra step, you could define a __str__ method in your class man so that when you pass it to str() or print() , it shows the name instead:

    # Inside class man
    def __str__(self):
        return self.name

That way your function could just do:

    return guy1

And when you print the return value of your function it actually prints the name.


If you cannot alter class man , here is an extremely convoluted and costly suggestion, that could probably break depending on context:

import inspect
def competition(guy1, guy2, counter1=0, counter2=0):
    guy1_name = ""
    guy2_name = ""
    for name, value in inspect.stack()[-1].frame.f_locals.items():
        if value is guy1:
            guy1_name = name
        elif value is guy2:
            guy2_name = name
    if counter1 > counter2:
        return guy1_name
    elif counter2 > counter2:
        return guy1_name
    else:
        return "Noone"

Valentin's answer - the first part of it at least (adding a name attribute to man ) - is of course the proper, obvious solution.

Now wrt/ the second part (the inspect.stack hack), it's brittle at best - the "variables names" we're interested in might not necessarily be defined in the first parent frame, and FWIW they could as well just come from a dict etc...

Also, it's definitly not the competition() function's responsability to care about this (don't mix domain layer with presentation layer, thanks), and it's totally useless since the caller code can easily solve this part by itself:

def competition(guy1, guy2, counter1=0, counter2=0):
    .......................
    some *ok* manipulations
    .......................
    if counter1>counter2:
        return guy1


def main():
    bob = man(172, 'green')
    bib = man(190, 'brown')

    winner = competition(bob, bib)
    if winner is bob:
        print("bob wins")
    elif winner is bib:
        print("bib wins")
    else:
        print("tie!")

Python prints the location of class objects in memory if they are passed to the print() function as default. If you want a prettier output for a class you need to define the __repr__(self) function for that class which should return a string that is printed if an object is passed to print() . Then you can just return guy1

__repr__ is the method that defines the name in your case. By default it gives you the object type information. If you want to print more apt name then you should override the __repr__ method

Check below code for instance

class class_with_overrided_repr:
    def __repr__(self):
        return "class_with_overrided_repr"

class class_without_overrided_repr:
    pass

x = class_with_overrided_repr()
print x    # class_with_overrided_repr

x = class_without_overrided_repr()
print x    #  <__main__.class_without_overrided_repr instance at 0x7f06002aa368>

Let me know if this what you want?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM