Python import: Object has no attribute - python

I've continually looked up solutions to this and I can't find a simple answer. I'm trying to create an object from an imported class, and then call a method on that object.
from MySchedule import *
my_schedule = MySchedule(self.driver)
my_schedule.navigate_to_my_schedule() # getting an error here
Error is
AttributeError: MySchedule object has no attribute 'navigate_to_my_schedule'
Code from MySchedule.py:
class MySchedule:
def __init__(self, driver):
self.driver = driver
self.nav_btn = self.driver.find_element_by_id('locButton_1')
self.header = self.driver.find_element_by_id('panelTitle_1')
def navigate_to_my_schedule(self):
self.nav_btn.click()

The problem is that you're using MySchedule as both the module name and the class name, and are using from MySchedule import *.
I'd recommend changing the import statement to
import MySchedule
and referring to the class as MySchedule.MySchedule.
For further discussion of wildcard imports, see Should wildcard import be avoided?

Related

Importing a class by referring to it with a variable?

Edit: This question was on the assumption that I could import parts of modules without importing the whole module. It turns out that isn't the case so I decided to just import the whole module with from ex45_extras import * anyway. That makes this question pointless, but I decided to not delete this question so that some other beginner with the same question can come here and find out the sad truth: You can't import modules as parts anyways
The following is the original question:
I'm a beginner so sry for the noob question. I want to call specific classes from a module with a variable. I don't want to call the whole module. And I need to do this using this class Nav() to control which classes are being imported. Is there a way to do this? Or is there a better solution?
class Nav():
def __init__(self):
print("This is class Nav")
def play(self):
current_scene_name = "A()" # this is where the variable is defined
from ex45_extras import current_scene_name # <- this is the one
x = Nav()
x.play()
Currently it's raising this error:
This is class Nav
Traceback (most recent call last):
File "D:\Programming\Python\LPTHW_Exs\ex45\test.py", line 11, in <module>
x.play()
File "D:\Programming\Python\LPTHW_Exs\ex45\test.py", line 7, in play
from ex45_extras import current_scene_name
ImportError: cannot import name 'current_scene_name' from 'ex45_extras' (D:\Programming\Python\LPTHW_Exs\ex45\ex45_extras.py)
Class names don't have a trailing () suffix — that's how you create an instance of one (i.e. by calling it).
Anyhow, if ex45_extras.py defines a class named A:
class A:
pass
Then you could import the class via a string containing its name, and then create an instance of it as shown below:
class Nav():
def __init__(self):
print("This is class Nav")
def play(self):
import ex45_extras
current_scene_name = 'A' # this is where the variable is defined
class_ = getattr(ex45_extras, current_scene_name) # Get class.
instance = class_() # Create instance of class.
print(f'{instance=}') # -> instance=<ex45_extras.A object at 0x010D4838>
x = Nav()
x.play()
guess it's because you're trying to import an string "A()" instead of a class A()

Why can't I import function from a class in the same directory?

In my builder/graph_builder.py, I have a class
class GraphBuilder(object):
def __init__(self):
pass
#staticmethod
def parse(path):
...
return path
Then in the same directory, I have a linker.py, and I want to import the 'parse' function:
from builder.graph_builder.GraphBuilder import parse
I am in PyCharm and it prompts that 'from builder.graph_builder.' is visible, but after that, it can't reference GraphBuilder and parse function.
Why is that?
The syntax is from MODULE import NAME, therefore
from builder.graph_builder import GraphBuilder
will work, but
from builder.graph_builder.GraphBuilder import parse
will not - builder.graph_builder.GraphBuilder is not a module.
It's not possible to import a Method from a Class in python
You have to, first import the class and after call the method. It happen even if it is a static method.
As graph_builder is located at same directory, you could refer graph_builder directly.
Furthermore GraphBuilder is a class, so you could instantiate and store parse function into a variable
You could try like this:
from graph_builder import GraphBuilder
if __name__=='__main__':
path="C:\\Users\\"
parse=GraphBuilder().parse
test=parse(path)

Can't Pickle Wrapper Class Object

All, I'm trying to parallelize some code using multiprocessing, and I've stripped my code down such that commenting the line of my main class
self.obs = Observer(self.guess)
causes the system to run error free. If I write
obs = Observer(self.guess)
It works, but if I write self.obs, I get
TypeError: can't pickle Observer objects
Here is the entire class I'm trying to import. It is just a wrapper for ephem.Observer, which had the same error when importing.
import numpy as np
from req import SETTINGS
from req.helpers import load_db, pack_into_vector, create_observer
class Observer:
def __init__(self, beta=np.zeros((2,))):
self.observer = create_observer(beta)
return
def __getstate__(self):
return {'observer': self.observer}
The error occurs on p.start() where
p = Process(target=selector,args=(first_guess, recording_queue, guess_queue))
I actually solved this. I guess the issue was with all of the self.___ methods/attributes of my selector class. I created an additional class, selector_wrapper, with an init method that created and ran the selector class. This worked perfectly.
In summary, creating a wrapper class with no methods other than init, and with no attributes, fixed the problem!

Correct use of static methods

I have following simplified class named Password.py in folder1:
import random
CHARS = "ABC"
class PasswordHelper(object):
#staticmethod
def generateChars(length):
return ''.join(random.choice(CHARS) for x in range(length))
Now I have another class TestClass.py in folder2:
sys.path.append('../folder1/')
import Password
class Tester:
def whatever(self):
print Password.generateChars(3)
def main():
x = Tester()
x.whatever()
# call main method
main()
When calling python TestClass.py I get the following error: AttributeError: 'module' object has no attribute 'generateChars'. Both folders are on the same level. Is there a problem with the way I import the class files or with the static method declaration itself?
Python is not Java.
Firstly, there is absolutely no point to either the Tester or the Password classes. If you're not storing state, then don't define a class. Make both whatever and generateChars into normal standalone functions.
However, assuming you're doing this just to learn about Python classes, you have not understood that a class does not equal a module in Python. Since you've imported the Password module, you still need to refer to the PasswordHelper class:
Password.PasswordHelper.generateChars(3)
Alternatively, you can import the PasswordHelper class:
from Password import PasswordHelper
...
PasswordHelper.generateChars(3)
Finally, please follow PEP8 for your module, class and function names.
You defined the function in a class, so you need to reference it with the classname too:
print Password.PasswordHelper.generateChars(3)
Alternatively, move the function out of the class definition, at which point you do not need to use #staticmethod at all:
import random
CHARS = "ABC"
def generateChars(length):
return ''.join(random.choice(CHARS) for x in range(length))
In Python, functions do not have to be part of a class definition.

Python import a module into one class only

I am trying to get a module to import, but only if an object of a specific class is called. For example:
class One(object):
try:
import OneHelper
except ImportError:
pass
def __init__(self):
# this function doesn't use OneHelper
...
def blah(self):
# this function does
OneHelper.blah()
This causes a NameError: global name 'OneHelper' is not defined when the One.blah() function is called. So far the only thing I have found that works is importing the module into the actual functions that use it. So:
class One(object):
def __init__(self):
# this function doesn't use OneHelper
...
def blah(self):
try:
import OneHelper
except ImportError:
pass
# this function does
OneHelper.blah()
But I don't want to have to import the module in each function I want to use it in, I want it to be available to the whole class, but only if an instance of that class is instantiated. Apologies if I'm not being clear enough...
The import OneHelper works fine in the class, making it a class attribute. You can verify this with dir(One) after defining your class -- there's your OneHelper attribute. One.OneHelper is a reference to the module. In an instance, of course, you may access it as self.OneHelper from your methods. (You could also continue to access it as One.OneHelper.)
Import it on __init__ and attribute to some property:
class One(object):
def __init__(self):
try:
import OneHelper
except ImportError:
self.OneHelper = None
else:
self.OneHelper = OneHelper
def blah(self):
if self.OneHelper:
self.OneHelper.blah()
Your example looks funny because if the module fails to import what is the point of calling it later?
You might also consider using global OneHelper before importing the module. This adds the OneHelper to the global namespace.

Categories

Resources