I am an APCS student so my primary language is Java but am currently writing a program that requires python which I know somewhat. I assume there is a way to call classes / methods outside the file in which they were created like in Java because they are both OO, but was wondering how I would go about doing this. Thanks.
Depending on how you go about packaging your code (IE: you may end up using a python package or simply a module) you will likely use the import statement in a very similar way as you do java. Some Examples:
import my_module
my_object = my_module.MyClass()
or
from my_module import MyClass
my_object = MyClass()
You use the import statement, where you either import the whole file or just the required class.
For example, my directory has file1.py and file2.py.
file2.py has a class named "A", which has the method print_hi().
So, in file1.py I do this:
from file2 import A
A.print_hi()
And I get the expected output.
Or, I could do this:
import file2
file2.A.print_hi()
which gives me the same output.But, you can't just import a method from a class which is present in another file --- you either import the file or the required class.
Thus, doing things like:
from file2.A import print_hi
or
from file2 import A.print_hi
won't work.
Related
I often do this:
└─ mymodule
├─__init__.py
├─ MyClass1.py
...
└─ MyClass2.py
And each file contains a single class, named accordingly MyClass1, MyClass2.
I know, I know, not pythonic of me, but I believe that convention should not limit my possibilities.
But, I encounter problems that I can not solve on my own - python import rules defy my logic.
Could you please help me, if not understand, but at least to have a way to do what I want. I want to compose my __init__.py so, that "mymodule" behaves as if all classes were in one file "mymodule.py".
I.e. from outside file, I want to be able to do:
from mymodule import MyClass1
And it would give me the class, and not the module, without having to do MyClass1.MyClass1.
Is there a way to do this in Python?
You can import it like this:
from mymodule.MyClass1 import MyClass1
In __init__.py:
from .MyClass1 import MyClass1
from .MyClass2 import MyClass2
Then you can use your import:
from mymodule import MyClass1
I am in the habit of using raw_input(...) for certain debugging. However, in python3 this has changed to input(...). Is there a way to define an alias at the top of my project, such as:
# __init__.py
raw_input = input
I tried the above, but it only worked in the file I added it to, and not any other files in that directory. I'd like this to work basically in every file within my python repository.
You can define all aliases in a separate file (e.g. aliases.py) then import said file where needed (i.e. import aliases).
The con with this method that you'll be referencing the alias through aliases.alias unless you make the import stricter (i.e. from aliases import raw_input) or if you don't care about avoiding a wildcard import (i.e. from aliases import *).
Additionally, if you don't mind another import in the aliases file you can use the builtins namespace:
import builtins
builtins.raw_input = input
You still have to define all aliases separate file (e.g. aliases.py) then import said file where needed (i.e. import aliases) but the advantage of using the builtins namespace is that you can use that import exactly as given.
You can do it by creating a module for creating the renaming function and then importing it to every file you want to like this:
First the module function declaration in alias.py
def raw_input(a):
return input(a)
Secondly, import to another file:
from alias import raw_input
x = raw_input("hello world")
print(x)
Sadly, you will have to make the import of the module to every file you want to use the renamed function.
Hope it works for you!
Put this at the top, and you will get exactly what you want.
import builtins
builtins.raw_input = builtins.input
It is guaranteed to work, but generally considered a bad practice (everybody will be confused with where is that raw_input defined)
Suppose I have a Python module "main.py":
import math # from the standard Python library
import my_own_module
...
foo = math.cos(bar)
And I also need to import the standard math module in "my_own_module.py":
import math
...
baz = math.sin(qux)
In this case I think import math in "main.py" is redundant and can be omitted.
What's best practice in this case:
Omit import math from "main.py" becuase it's redundant? Or,
Keep import math in "main.py" to clarify that the code in that module requires it?
The reference to math.cos in main.py means that import math is required in main.py, regardless of whether my_own_module.py imports it or not. It is not redundant, and it cannot be omitted (and if you try to omit it, you'll get an error).
import math
does something else than simply including the full text of one file into the other.
It introduces a new namespace with the name math, and this math name will be known in your current namespace.
If you omit the
import math
from your main.py file, your command
foo = math.cos(bar)
becomes illegal, as the math symbol will be not (recognized) in the main.py namespace.
This is not like, eg #include in C++. The import is not optional. Importing a module is required to be able to refer to its contents. This is true for every single file that does it.
A good question. The short answer is yes, if you use a math function in a py file then you need to import the module at the top regardless of how many times its imported elsewhere.
It gets interesting when we throw a thrid file into the mix, lets call this "explanation.py"
And lets suppose that your "main.py" becomes "my_functions.py" and contains a function called foo:
#my_functions.py
import math
import my_own_module
def foo(bar):
return math.cos(bar)
and in my_own_module.py:
#my_own_module.py
import math
def bar(foo):
return math.sin(foo)
and finally explanation.py (new main())
#main.py
import my_functions
import my_own_module
bar = my_functions.foo(10)
foo = my_own_module.bar(10)
print(foo)
print(bar)
Notice how you DO NOT need to add math if you call the functions imported from another file. I hope that might add further clarity to your enquiry :)
However it might be worth noting that this would exclude maths from the current namespace, therefore rendering any further calls to the math functions useless.
I have a directory structure like this:
foo/
__init__.py
printsum.py
'''
def printsum(x,y):
print("sum is " + str(x+y))
'''
bar.py
'''
def printsum(x,y):
print("sum is " + str(x+y))
'''
example.py
'''
#!/usr/bin/env python3
import foo.printsum
import bar
foo.printsum.printsum(1,2)
bar.printsum(3,4)
'''
The file example.py is meant to be run as a script, while foo and bar are meant to be imported modules. I would like to make the namespace of foo like bar. That is - I don't want the double printsum.printsum. I don't want all of the foo module to be saved in one big monolithic file, like bar.py. I want the foo.printsum() method to be saved in a file by itself, but I want printsum() to exist at the foo. namespace level.
Can this be done somehow?
Import the functions in __init__py.
foo/__init__py:
from .printsum import printsum
(If you are using python2, you might need to remove the dot or use full import path. Rules for relative import paths are stricter in python 3)
Then you can call the function directly from foo:
import foo
foo.printsum(...)
The foo import will run __init__. You can add some prints in there as well if you want proof. This is a perfectly normal way to expose functionality in package modules. You can also do * imports, but that is generally not recommended. Import strictly what you want to expose.
__init__ in other words is a place you can glue stuff to the package, but also do automatic initialisation that triggers in the import.
Also look up the __all__ keyword. It can be extremely useful to hide code that is not relevant for a user of the package or module.
I'm a beginner to python, and have written a module that looks something like this:
# filename: mymodule.py
import numpy as np
from datetime import datetime
def a():
...<stuff>...
def b():
...<stuff>...
The consensus in this thread generally (and in agreement with PEP8) seems to be that import statements should be at the file header. However, now when I import mymodule, running dir(mymodule) shows that objects np and datetime are part of mymodule -- which offhand, seems inefficient and "sloppy". It seems one way to preserve only classes and defs would be some kind of conditional deletion via dynamic iteration over globals() (which after trying and failing for a bit, seems really elusive), or just use the del keyword on everything.
The main question: can I do this, and can I do this dynamically instead of explicitly? Don't the defs work independently, regardless of whether the header modules are part of the import? Otherwise from <x> import <y> would break every time, I would think.