2
class person:    
    def __init__(self, name, gender):
        self.name=name
        self.gender=gender

b=person('bob','male')
b.name='bob'
b.gender='male'

Now I have a string 'bob', how can I get the object b?

Thanks a lot for all the answers and help. Let me be more clearer. If I assume there can only be unique names and my goal is to find bob's gender (I only know 'bob' but I do not know b). Is there a way to do so?

5
  • Your purpose? This probably isn't the easiest way to accomplish what you want. Commented Mar 29, 2016 at 23:20
  • You could create a PersonFinder class? Need more info Commented Mar 29, 2016 at 23:22
  • If you just want to be able to retrieve an object given a string, you can always just use a dictionary to map the string to the object. Commented Mar 29, 2016 at 23:23
  • Do you want to find all objects in your program that use the string 'bob' or just person objects that use that string? Can there be multiple person objects using bob? Commented Mar 29, 2016 at 23:58
  • Thanks a lot for all the answers and help. Let me be more clearer. If I assume there can only be unique names and my goal is to find bob's gender (I only know 'bob' but I do not know b). Is there a way to do so? Commented Mar 30, 2016 at 1:05

4 Answers 4

3

You can't, because - just like in the real world - there can be multiple people with the name 'bob'.

Sign up to request clarification or add additional context in comments.

1 Comment

even before edit, the example only had one person named bob, so this is not really an answer.
1

This assumes you have some way of knowing who all of your people are. Let's say you have a list of people, and you want to find 'bob'.

a = person('anne', 'female')
b = person('bob', 'male')
c = person('cathy', 'female')

people = [a, b, c]

Now you can check each person to see if their name is 'bob'.

maybe_bob = [pers for pers in people if pers.name == 'bob']

If 'bob' exists, we can access his object by calling the first item in the list.

try:
    bob = maybe_bob[0]
except IndexError:
    print "No one named 'bob'."

Of course, like wim said, this will break down if there are multiple people named 'bob' in your list.

Comments

1

Since bob is unique you can get the instance with ast and pull the gender from that:

import inspect
import importlib
import ast   

class FindAttr(ast.NodeVisitor):
    def __init__(self, name):
        self.name = name
        self.b = None

    def visit_Assign(self, node):
        for t in node.targets:
            if isinstance(t, ast.Attribute) and hasattr(node.value, "s"):
                if node.value.s == self.name:
                    self.b = (getattr(mod,t.value.id))
                    return


mod = "test"
mod = importlib.import_module(mod)
p = ast.parse(inspect.getsource(mod))

f = FindAttr("bob")
f.visit(p)

using your example in test.py:

In [4]: mod = "test"

In [5]: mod = importlib.import_module(mod)

In [6]: p = ast.parse(inspect.getsource(mod))

In [7]: f = FindAttr("bob")

In [8]: f.visit(p)


In [9]: print(f.b)
<test.person instance at 0x7f2a78e623f8>
In [10]: print(f.b.gender)
male

In [11]: print(f.b.name)
bob
In [12]: print(f.b.__class__)
test.person

Comments

0

having a dict for reverse lookup of objects is probably what you want:

class person:   
    people_database = {} 
    def __init__(self, name, gender):
        person.people_database[name] = self 
                  #add this instance to the database
                  #possibly overriding the previous entry with this name
        self.name=name
        self.gender=gender

b=person('bob','male')

print (person.people_database["bob"])
print (b)
print(b is person.people_database["bob"])

although do know that if you change the name of a person like:

b=person('bob','male')
b.name = "susan"

this technique will obviously not work properly.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.