I was reading a book Programming Python (4th edition) and I am stuck at a problem with a piece of code including getattr
. It is a loop for finding an icon file but I can't figure where it is searching (in what order). I have basic knowledge of using getattr
like it searches the __dict__
for names, but couldn't figure this one out.
mymod = __import__(__name__) # import self for dir
path = __name__.split('.') # poss a package path
for mod in path[1:]: # follow path to end
mymod = getattr(mymod, mod) # only have leftmost
mydir = os.path.dirname(mymod.__file__)
myicon = os.path.join(mydir, self.iconmine)
The comments are from the book. The last comment says "only have leftmost" so why run the loop if we want
the leftmost - can't we do path[-1]
instead?
Suppose you are working on a python project in the folder /home/py_project/
If you are coding a module (.py file) using the following path:
/home/py_project/modules/my_file.py
and the modules are defined in /home/py_project/modules/__init__.py
then,
mymod = __import__(__name__) # import self for dir
print(mymod)
yields: <module 'modules' from '/home/py_project/modules/__init__.py'>
path = __name__.split('.')
print(path)
yields: ['modules', 'my_file']
The for mod in path[1:]
is slicing the previous list and getting all items from 1 to inf, in this case, only 'my_file' is considered.
for mod in path[1:]: # follow path to end
mymod = getattr(mymod, mod) # only have leftmost
# same as mymod = modules.my_file
mydir = os.path.dirname(mymod.__file__)
print(mydir)
yields: /home/py_project/modules
myicon = os.path.join(mydir, self.iconmine)
print(myicon)
yields: /home/py_project/modules/path_to_self.iconmine # I don't know what self.iconmine is, you didn't mention it.
Always print (or debug) the steps to the understand the code.
The getattr()
method returns the value of the named attribute of an object. If not found, it returns the default value provided to the function. For example:
The syntax of getattr() method is:
getattr(object, name[, default])
The above syntax is equivalent to:
object.name
Example:
class Person:
name = "Louis"
person = Person()
print('Name:', person.name)
print('Name:', getattr(person, "name")) # using getattr() is the same as person.name