Reputation: 77
I am trying to implement this repetitive block of code below, by creating objects with name fetched from a list instead of creating objects and passing instance repeatedly .
class waittill:
def __init__(self,path):
self.imagepath = os.path.join("C:\python\python_projects\pyautogui\images", path)
loaded=waittill("loaded.png")
agree=waittill("agree.png")
firstname=waittill("firstname.png") #This works absolutely fine
loginid=waittill("loginid.png") #I wish repetition could be avoided
password=waittill("password.png")
loginbutton=waittill("loginbutton.png")
customerlist=waittill("customerlist.png")
loginpage=waittill("loginpage.png")
customerinfo=waittill("customerinfo.png")
profile=waittill("profile.png")
is it possible to write a more elegant code, like cycling through an list to create objects
images=["loaded.png","agree.png","firstname.png","loginid.png","password.png","loginbutton.png","logout.png","middlename.png","lastname.png","submit.png",\
"customerlist.png","loginpage.png","customerinfo.png","profile.png"]
for each_image in images:
a,b=each_image.split(".")
b=(a+"."+b)
image=b.strip()
name=a.strip()
name=waittill(image) #this is where the problem lies, its repeatedly naming the object *name* and not say *loaded* or *agree*.
Upvotes: 0
Views: 2461
Reputation: 3287
A dictionary comprehension can help with this:
images=["loaded.png","agree.png","firstname.png","loginid.png","password.png","loginbutton.png","logout.png","middlename.png","lastname.png","submit.png",\
"customerlist.png","loginpage.png","customerinfo.png","profile.png"]
image_objects = {k.split('.')[0]: waittill(k) for k in images}
To access a specific object say "agree", just index the image_objects dictionary like so:
agree = image_objects['agree']
Upvotes: 0
Reputation: 110271
I see your case, but it makes sense to do it the otherway around: have the variable name hardcoded, since you will be referring to it, and use folder and sufix information to get the image-file name.
In Python previous to 3.6, there is no way for an oject to automatically guess the name it is assigned too (though it can be done with metaclasses), so creating your objects as a dictionary, and later populating your module with the dict contents might be an option:
names = ['loaded', 'agree', 'firstname', 'loginid', 'password', 'loginbutton', 'logout', 'middlename', 'lastname', 'submit', 'customerlist', 'loginpage', 'customerinfo', 'profile']
class waittill:
def __init__(self, name):
self.imagepath = os.path.join(r"C:\python\python_projects\pyautogui\images\{}.png".format(name))
objects = {name:waittill(name) for name in names}
for name, obj in objects.items():
globals()[name] = obj
(Note another source of hard-to-debug problem in your code: if you insist in use \
as a path separator, you should prefix the strings containig paths with r"
- otherwise your path will fail if you have folders starting with some letters like n, t and others.
Also, I am setting the names automatically in the module namespace using globals()
, but that is not a good practice. You could use a class as namespace to the exactly the same - in that case, just put the code above inside a class body (not inside a method), and use locals()
instead of globals()
class images(object):
for name in names:
locals(name) = waittill(name)
Upvotes: 1