How can I specify the package when instantiating a class? - python-3.x

I have many classes with the same name in different packages. Take the following directory structure as an example:
From within the constructor of the templates/Person class, how can I declare an instance of rules/Person?
The code I expected to work (but has an error on line 10) is as follows:
from Template import Template
import rules
class Person(Template):
def __init__(self):
super(Person, self).__init__('Person')
self.rules = [
rules.Person() #this is an error
]

PEP328 has the answer, I think.
from .myfolder import Template as Template
from .myfolder1 import Template as Template1
from .myfolder2 import Template as Template2
from pip_installed_library1 import Template as Template3
from pip_installed_library2 import Template as Template4
Using this pattern they never share names.

Related

Import __all__ from Python module given by variable

I wan to import all the functions and class into a module/file of Python in high level file just passing a variable that contains the low level file name.
I have a application with several module like:
__all__ = ['MyClass1', 'my_function1']
class MyClass1():
pass
def my_function1():
pass
that previous was import at the high level file as:
from sub_module1 import *
from sub_module2 import *
...
# To direct use, of the different subfiles:
obj1 = MyClass1()
obj2 = MyClass2()
The application became a plugin based and I have to dynamic import all module into a folder and provide direct access to all objects defined into __all__ of those submodules.
The code bellow imports fine the submodules but I don not give my direct access to the directives defined into __all__ of those files.
from os import path
from importlib import import_module
directory_name = ## Define the plugins dir.
for importer, package_name, _ in iter_modules([directory_name]):
module_specification = importlib.util.spec_from_file_location(
package_name, path.join(directory_name, package_name + '.py'))
module_loader = importlib.util.module_from_spec(module_specification)
module_specification.loader.exec_module(module_loader)
How do I put those object define into __all__ of the submodules inside locals() of the high module?

Loading a class of unknown name in a dynamic location

Currently I am extracting files to the temp directory of the operating system. One of the files is a Python file containing a class which I need to get a handle of. The Python's file is known, but the name of the class inside the file is unknown. But it is safe to assume, that the there is only one single class, and that the class is a subclass of another.
I tried to work with importlib, but I am not able to get a handle of the class.
So far I tried:
# Assume
# module_name contains the name of the class and -> "MyClass"
# path_module contains the path to the python file -> "../Module.py"
spec = spec_from_file_location(module_name, path_module)
module = module_from_spec(spec)
for pair in inspect.getmembers(module):
print(f"{pair[1]} is class: {inspect.isclass(pair[1])}")
When I iterate over the members of the module, none of them get printed as a class.
My class in this case is called BasicModel and the Output on the console looks like this:
BasicModel is class: False
What is the correct approach to this?
Edit:
As the content of the file was requested, here you go:
class BasicModel(Sequential):
def __init__(self, class_count: int, input_shape: tuple):
Sequential.__init__(self)
self.add(Input(shape=input_shape))
self.add(Flatten())
self.add(Dense(128, activation=nn.relu))
self.add(Dense(128, activation=nn.relu))
self.add(Dense(class_count, activation=nn.softmax))
Use dir() to get the attributes of the file and inspect to check if the attribute is a class. If so, you can create an object.
Assuming that your file's path is /tmp/mysterious you can do this:
import importlib
import inspect
from pathlib import Path
import sys
path_pyfile = Path('/tmp/mysterious.py')
sys.path.append(str(path_pyfile.parent))
mysterious = importlib.import_module(path_pyfile.stem)
for name_local in dir(mysterious):
if inspect.isclass(getattr(mysterious, name_local)):
print(f'{name_local} is a class')
MysteriousClass = getattr(mysterious, name_local)
mysterious_object = MysteriousClass()

Replace package import in a module

I use a module that imports a function as a package import using relative import dot notation:
from .utils import target_func
class ClassINeed:
def function_i_call(self):
return target_func()
I want to import ClassINeed with from classineed import ClassINeed but replace target_func with a function of my own. Problem is, target_func is not part of the class I am importing. Therefore I do not see a way to access it. What would be a way to accomplish this?
On top of from classineed import ClassINeed, also do a import classineed then override the target_func as needed via classineed.target_func = lambda : 'hello!' for example.
P.S. Referring to the class ClassINeed with classineed.ClassINeed might be cleaner if you already have import classineed.

Python - how to import class form another python file

i have two files test.py and site.py in c:\newfolder. I want to import siteElements class from site.py to test.py.....I have written
from site import siteElements
siteElements = SiteElements(webdriver)
but its not working.....
ImportError : cannot import name 'siteElements'
You have a mismatch, what you should do is this:
from modulefile import classname
variable_object = classname(something)
Instead, it seems you do:
from modulefile import classname
classname = variable_object(something)
If we assume that you spelled the class correct, your code should read:
from site import siteElements
variable_object_name = siteElements(webdriver)
Alternatively you can do this like this, introducing an alias to the imported class (make sure the alias name is unique):
from site import siteElements as se
variable_object_name = se(webdriver)
You did not post the "site" module, so you need to check that siteElements is indeed the correct name/spelling of your class.

How do I get a basic working example for django-user-account?

I followed the installation instructions on django-user-accounts.
When calling http://[mysite]/account/signup
I could see:{# This template intentionally left blank to satisfy test suites. Your project should always provide a site_base.html itself. #} (and I take it as a good sign, I'll add my base template later).
After that, i created an app: ./manage.py startapp myapp_account
...and filled it with the minimum code from the "Usage" page of the manual mentioned above as i want to get a basic working register/login/out.
Now i get an error when calling http://[mysite]/account/signup/:
Exception Value: 'module' object has no attribute 'views'
Exception Location: /var/www/venv/django_1/django_1/urls.py in <module>, line 10
Python Executable: /var/www/venv/bin/python3.4
my code:
urls.py (main project called django_1):
from django.conf.urls import patterns, include, url
import myapp_account
urlpatterns = patterns('',
# this is line 10 in my case:
url(r'^account/signup/$', myapp_account.views.SignupView(),name="account_signup"),
url(r'^account/', include('account.urls')),
)
myapp_account/views.py:
import account.views
import account.forms
import myapp_account.forms
class SignupView(account.views.SignupView):
form_class = myapp_account.forms.SignupForm
def after_signup(self, form):
self.create_profile(form)
super(SignupView, self).after_signup(form)
def create_profile(self, form):
profile = self.created_user.get_profile()
profile.birthdate = form.cleaned_data["birthdate"]
profile.save()
class LoginView(account.views.LoginView):
form_class = account.forms.LoginEmailForm
myapp_account/forms.py
from django import forms
from django.forms.extras.widgets import SelectDateWidget
import account.forms
class SignupForm(account.forms.SignupForm):
birthdate = forms.DateField(widget=SelectDateWidget(years=range(1930, 2010)))
Is there a simpler way do get it working and be on the right track to extend the user accounts step by step?
As usual the answer was in the manual Django, Class-based views
:
Import the class based view directly
Call the class based view directly in the url
updated urls.py (main)
from django.conf.urls import patterns, include, url
from myapp_account.views import SignupView # <- import class based view
urlpatterns = patterns('',
# call class based view directly:
url(r'^account/signup/$', SignupView.as_view(), name="account_signup"),
url(r'^account/', include('account.urls')),
)
Still i'd be happy if someone cloud point me to a well made example of django-user-accounts.

Resources