I am trying to create a new module and method as part of an existing library.
The existing library is called Bly.Pht. I create a new *.py file in this directory called Distance.py. In Distance.py I have the following:
class Distance:
def __init__(self, handle):
self.handle = handle
def test_func(t1, t2):
print "correctly executing"
From the Python shell, I do the following:
from Bly.Pht import Distance #this works fine
dist = Distance.test_func(input1, input2)
I get the error 'module' object has no attribute 'test_func'
Can anyone advise as to why this is happening?
Many thanks.
You are not importing the Distance class, you are importing the module that contains the Distance class. It can be fixed as:
dist = Distance.Distance.test_fund(input1, input2)
If you don't plan on including other functionality in Distance.py, it's probably a better idea to put the class definition in Bly/Pht/__init__.py or in Bly/Pht.py, in which case you could import it as you did. (Unlike other languages, Python doesn't encourage each class having its own file).
Python is not Java. If you created a file called Distance.py that defines a class called Distance, you need to from Bly.Pht.Distance import Distance. Or, if there's no good reason to make it a class, just write the method directly in the module.
Related
I am making a contact list system for a class project and used tkinter to make my gui and sqlite3 for the database. I made a bunch of methods that have basically solved the problem but I noticed the question paper says that the functions need to be in a class. How do I put these functions under a class without messing everything up. I am using python3.
A function in a module is similar to a static method in a class. Without knowing any of your app's specifics:
If you have a function that does what you want
def f():
return 'g'
and you want to encapsulate it in a class
class Q:
pass
just assign it as a static method to that class
Q.f = staticmethod(f)
Whenever you need to use that function you have to call it via the class
>>> Q.f()
g
This is similar to what happens when you import a module that has functions - you import the module and call the functions using the module name (the functions are module attributes) - modulename.func().
I really have no idea how this fits with your need or what any downsides might be.
I am trying to implement a small library for Python 3.5 but keep struggling with how to correctly handle the structuring of the packages/modules and how to get the imports to work.
I keep running into the problem where python complains of being unable to import some name with an error like
ImportError: cannot import name 'SubClass1'
This seems to happen when "SubClass1" needs to import some other module but that other module also needs to know about SubClass1 (a cyclic import).
I need the cyclic import in my library because the base class has a factory method that creates the proper subclass instances (there are also other situations where cyclic imports are needed, e.g. checking the type of a function argument needs the import of where that type is defined, but that module may itself need the class where that check is done: another cyclic dependency!)
Here is example code:
Root directory contains the subdirectory dir1. The directory dir1 contains and empty file init.py, a file baseclass.py and a file subclass1.py.
The file ./dir1/subclass1.py contains:
from . baseclass import BaseClass
class SubClass1(BaseClass):
pass
The file ./dir1/baseclass.py contains:
from . subclass1 import SubClass1
class BaseClass(object):
def make(self,somearg):
# .. some logic to decide which subclass to create
ret = SubClass1()
# .. which gets eventually returned by this factory method
return ret
The file ./test1.py contains:
from dir1.subclass1 import SubClass1
sc1 = SubClass1()
This results in the following error:
Traceback (most recent call last):
File "test1.py", line 1, in <module>
from dir1.subclass1 import SubClass1
File "/data/johann/tmp/python1/dir1/subclass1.py", line 1, in <module>
from . baseclass import BaseClass
File "/data/johann/tmp/python1/dir1/baseclass.py", line 1, in <module>
from . subclass1 import SubClass1
ImportError: cannot import name 'SubClass1'
What is the standard/best way to solve this problem, ideally in a way that is backwards compatible to python 2.x and python 3 up to version 3.2?
I have read elsewhere that importing the module instead of something from a module may help here but I do not know how to just import the module (e.g. subclass1) in a relative way because "import . subclass1" or similar does not work.
Your issue is caused by a circular import. The baseclass module is trying to import SubClass1 from the subclass1 module, but subclass is trying to import BaseClass right back. You get NameError because the classes haven't been defined yet when the import statements are running.
There are a few ways to solve the issue.
One option would be to change your style of import. Instead of importing the classes by name, just import the modules and look up the names as attributes later on.
from . import baseclass
class SubClass1(baseclass.BaseClass):
pass
And:
from . import subclass1
class BaseClass:
def make(self,somearg):
# ...
ret = subclass1.SubClass1()
Because SubClass1 needs to be able to use BaseClass immediately at definition time, this code may still fail if the baseclass module is imported before subclass1. So it's not ideal
Another option would be to change baseclass to do its import below the definition of BaseClass. This way the subclass module will be able to import the name when it needs to:
class BaseClass:
def make(self,somearg):
# .. some logic to decide which subclass to create
ret = SubClass1()
from .subclass1 import SubClass1
This is not ideal because the normal place to put imports is at the top of the file. Putting them elsewhere makes the code more confusing. You may want to put a comment up at the top of the file explaining why you're delaying the import if you go this route.
Another option may be to combine your two modules into a single file. Python doesn't require each class to have its own module like some other languages do. When you have tightly coupled classes (like the ones in your example), it makes a lot of sense to put them all in one place. This lets you avoid the whole issue, since you don't need any imports at all.
Finally, there are some more complicated solutions, like dependency injection. Rather than the base class needing to know about the subclasses, each subclass could register itself by calling some function and passing a reference to itself. For example:
# no imports of subclasses!
def BaseClass:
subclasses = []
def make(self, somearg):
for sub in self.subclasses:
if sub.accepts(somearg):
return sub()
raise ValueError("no subclass accepts value {!r}".format(somearg))
#classmethod
def register(cls, sub):
cls.subclasses.append(sub)
return sub # return the class so it can be used as a decorator!
And in subclass.py
from .baseclass import BaseClass
#BaseClass.register
class SubClass1(BaseClass):
#classmethod
def accepts(cls, somearg):
# put logic for picking this subclass here!
return True
This style of programming is a bit more complicated, but it can be nice since it's easier to extend than a version where BaseClass needs to know about all of the subclasses up front. There are a variety of ways you can implement this style of code, using a register function is just one of them. One nice thing about it is that it doesn't strictly require inheritance (so you could register a class that doesn't actually inherit from BaseClass if you wanted to). If you are only dealing with actual inheriting subclasses, you might want to consider using a metaclass that does all the registration of subclasses for you automatically.
I am having some trouble with dynamically importing Classes and attempting to run functions in said classes. This is my problem, specifically.
I have a python script dyn_imports.py in a director called dynamic_imports. Inside this folder is a subdir called scripts. In this scripts directory there is an __init__.py and a python class called AbhayScript.py. In the class AbhayScript, there is a function called say_hello()
My objective is: From dyn_imports.py, I would like to be able to import scripts.AbhayScript and call the function say_hello() in AbhayScript
So far, I have attempted a variety of options including __import__, importlib.import_module and pydoc.locate. All of these options give me access to the module AbhayScript but when I try a getattrs() or try to call the object, I get an error stating that its not callable or has no attribute.
dyn_imports.py - One of my experiments
myclass = 'scripts.AbhayScript'
import importlib
mymod = importlib.import_module(myclass)
mod,newclass = myclass.rsplit('.',1)
ncls = getattr(mod,newclass) #throws an AttributeError that 'str' object has no attribute
AbhayScript.py code
class AbhayScript(object):
def say_hello(self):
print 'Hello Abhay Bhargav'
The directory structure is as follows
The init.py in the scripts folder is empty.
I have attempted nearly all the solutions in Stackoverflow, but I am a little flummoxed by this one. What am I doing wrong?
I realize what I was doing wrong. I was importing the module and not referencing the class in the getattr function. I made the class declaration explicit in the __import__ function and in the getattr function and I was subsequently able to gain access to the functions in the class
Here's the code in dyn_imports.py
myclass = 'scripts.AbhayScript'
mod = __import__(myclass, fromlist = ['AbhayScript']) #class explicit
klass = getattr(mod, 'AbhayScript') #explicit class
klass().say_hello() #calls the function as desired
The online search has been less then helpful in this matter. I'm trying just to create a module with a few classes and test it. I haven't been able to pass the first part.
I have created a simple class with 3 attributes and their getters methods so I see their attributes from a "main" method (I guess)
I need to create a few objects of this class so I can used the later.
the class definition is
class Person:
def __init__(self, n, a, s):
self.name = n
self.age = a
self.sex = s
def getAge(self):
return self.age
def getSex(self):
return self.sex
I saved this file in a test.py file, the from the shell I import it but then I keep getting the same error when I instantiate and object
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
x = Person('myname', 10, 'm')
NameError: name 'Person' is not defined
test.py is located in C:/Python3.x directory so I really don't get this error.
When I just type the whole class in the shell and instantiate objects everything works but that is useless in my case since the modules will be growing over time.
Please answer only if you are willing to help, don't send me to the same tutorials which don't explain anything without the shell. I need to work with modules and understand the meaning of that error im getting.
Your class should probably derive from object, but that's not the cause of the error. You're probably trying to access a name that's not explicitly imported. You can either import a whole module, or a name from a module.
import test
test.Person()
Or
from test import Person
Person()
Or both. No error, but not much sense made either.
You may be tempted to type from test import * to imitate behavior of other languages, but this is in most cases considered bad style in python. Explicit is better than implicit.
To learn more about how imports work, try to import test and then dir(test). Or import itertools and dir(itertools), or download some nice codebase like Werkzeug, read the code to see how it's structured and then try navigating it via the REPL.
Relatively new to Python, and I saw the following construct in the PyFacebook library (source here: http://github.com/sciyoshi/pyfacebook/blob/master/facebook/init.py#L660). I'm curious what this does because it appears to be a class that inherits from itself.
class AuthProxy(AuthProxy):
"""Special proxy for facebook.auth."""
def getSession(self):
"""Facebook API call. See http://developers.facebook.com/documentation.php?v=1.0&method=auth.getSession"""
...
return result
def createToken(self):
"""Facebook API call. See http://developers.facebook.com/documentation.php?v=1.0&method=auth.createToken"""
...
return token
what is this doing?
Tangentially related, I'm using PyDev in Eclipse and it's flagging this as an error. I'm guessing that's not the case. Anyway to let Eclipse know this is good?
The class statement there doesn't make the class inherit from itself, it creates a class object with the current value of AuthProxy as a superclass, and then assigns the class object to the variable 'AuthProxy', presumably overwriting the previously assigned AuthProxy that it inherited from.
Essentially, it's about the same as x = f(x): x isn't the value of f on itself, there's no circular dependence-- there's just the old x, and the new x. The old AuthProxy, and the new AuthProxy.
It's using the AuthProxy imported from a different module (check your imports) and deriving from it.
The "former" AuthProxy is created by __generate_proxies (it's not very nice code, there is even an exec and eval in it :)), but the author wanted also define some methods on top of it.
To make Eclipse stop whining about it, do this:
class AuthProxy(AuthProxy): ##UndefinedVariable