Check if object attribute name appears in a string python
<p>I want to:</p>

<ul>
<li>check whether a string contains an object property</li>
<li>if it does then access the attribute</li>
</ul>

<p>So for an object of class </p>

<pre><code>class Person(object):
    name = ""
    age = 0
    major = ""

    def __init__(self, name="", surname="", father="", age =0):
        self.name = name
        self.surname = surname
        self.father = father
        self.age = age
        self.identity = name +" "+ surname
    def __str__(self):
        return self.identity

    __repr__ = __str__
</code></pre>

<p>and object</p>

<pre><code>person = Person("Earl", "Martin", "Jason", 40)
</code></pre>

<p>I would like for string "What is the name"
to return person.name 
(I already know which object the string is about)</p>

<p>The most basic solution would be to do cases for each property being there but the actual code has quite a few and I am sure I don't manually have to write them out, I am just new to programming so I am not sure what syntax is used for this</p>

<p>Any help appreciated </p>

<p>As others have noted, <a href="https://docs.python.org/3/library/functions.html#getattr" rel="nofollow"><code>getattr</code></a> is generally useful.</p>

<p><a href="https://docs.python.org/3/library/functions.html#hasattr" rel="nofollow"><code>hasattr</code></a> is of lesser utility; internally, it's basically a <code>getattr</code> call in a <code>try</code>/<code>except AttributeError:</code> block (if <code>AttributeError</code> occurs, it returns <code>False</code>, no exception means <code>True</code>), so if you're considering code like:</p>

<pre><code>if hasattr(myobj, attrname):
    attr = getattr(myobj, attrname)
    ...
</code></pre>

<p>just use:</p>

<pre><code>try:
    attr = getattr(myobj, attrname)
except AttributeError:
    pass
else:
    ...
</code></pre>

<p>to avoid doubling the number of LEG<strong>B</strong> lookups, function calls and attribute lookups.</p>

<p>Alternatively, for repeatedly pulling named attribute(s), <a href="https://docs.python.org/3/library/operator.html#operator.attrgetter" rel="nofollow"><code>operator.attrgetter</code></a> basically lets you make an optimized version of <code>getattr</code> that pre-binds the attribute name to lookup (making it ideal for use with stuff like the <code>map</code> and <code>filter</code> functions, as it makes them more efficient than their equivalent listcomps/genexprs).</p>

<p>On top of those, depending on what your goal is, <a href="https://docs.python.org/3/library/functions.html#dir" rel="nofollow">the <code>dir</code></a> and (slightly less reliably, due to issues with classes <a href="https://docs.python.org/3/reference/datamodel.html?highlight=__slots__#object.__slots__" rel="nofollow">that use <code>__slots__</code> to define a known set of variables to reduce memory usage and prevent auto-vivification</a>) <a href="https://docs.python.org/3/library/functions.html#vars" rel="nofollow"><code>vars</code> function</a>s may be useful.</p>

<p>For example, in your example case of pulling any attributes corresponding to a word from a string, you could do a bulk identification of legal attribute names using <code>vars()</code>/<code>dir()</code> and your choice of <code>filter</code> or <code>set</code> operations (or a mix) depending on the importance of order, uniqueness, etc.:</p>

<pre><code>from future_builtins import filter  # Only on Py2, not Py3
import operator
import re

def query_obj(obj, querystr):
    # Extract list of legal attribute names from string
    words = re.findall(r'\w+', querystr)

    # Reduce to names present on object's __dict__; no need to construct temporaries
    attrnames = filter(vars(obj).__contains__, words)
    # Alternate if __slots__ might be an issue (temp list &amp; frozenset):
    attrnames = filter(frozenset(dir(obj)).__contains__, words)
    # Or combine the two to be sure (on Py3, use .keys() instead of .viewkeys())
    # (temp list and set):
    attrnames = filter((vars(obj).viewkeys() | dir(obj)).__contains__, words)

    # Convenient way to get all names discovered at once; returns single object
    # for single attr, tuple of objects for multiple attrs:
    return operator.attrgetter(*attrnames)(obj)

    # If you want a tuple unconditionally, use this instead:
    return tuple(getattr(obj, name) for name in attrnames)

    # Or to only return the first attribute encountered, raising StopIteration
    # if no attributes are found:
    return next(getattr(obj, name) for name in attrnames)
</code></pre>

<p>Then usage is:</p>

<pre><code>&gt;&gt;&gt; person = Person("Earl", "Martin", "Jason", 40)
&gt;&gt;&gt; query_obj(person, "What is the name?")
'Earl'  # Would be ('Earl',) in unconditional tuple case
&gt;&gt;&gt; query_obj(person, "What is the name and surname?")
('Earl', 'Martin')  # Would be 'Earl' in single return case
</code></pre>

python string python-2.7 class object