I was just curious if it was possible to create a module object inside python at runtime, without loading from any python file. The purpose of this would be to create a new empty namespace where other objects can then be stored subsequently. If this is not possible, is there another way to make and pass namespaces in python without saving to disk?
You can use a class with static methods.
class Namespace:
#staticmethod
def greet():
print "hello, world!"
In Python 3 the #staticmethod decorator is not needed.
You can use a simple class:
class Namespace:
pass
Now, to create a new namespace:
n = Namespace()
To store things in the namespace:
n.foo = 1
def square(x):
return x*x
n.squared = square
To refer to things in the namespace:
print n.foo
print n.squared(12)
To pass the namespace:
def func_requiring_a_namesapce(space):
print space.foo
func_requiring_a_namespace(n)
You could use a dictionary?
Modules Are Like Dictionaries
You know how a dictionary is created and used and that it is a way to map one thing to another. That means if you have a dictionary with a key 'apple' and you want to get it then you do this:
mystuff = {'apple': "I AM APPLES!"}
print mystuff['apple']
Imagine if I have a module that I decide to name mystuff.py and I put a function in it called apple. Here's the module mystuff.py:
# this goes in mystuff.py
def apple():
print "I AM APPLES!"
Once I have that, I can use that module with import and then access the apple function:
import mystuff
mystuff.apple()
I could also put a variable in it named tangerine like this:
def apple():
print "I AM APPLES!"
# this is just a variable
tangerine = "Living reflection of a dream"
Then again I can access that the same way:
import mystuff
mystuff.apple()
print mystuff.tangerine
Refer back to the dictionary, and you should start to see how this is similar to using a dictionary, but the syntax is different. Let's compare:
mystuff['apple'] # get apple from dict
mystuff.apple() # get apple from the module
mystuff.tangerine # same thing, it's just a variable
In the case of the dictionary, the key is a string and the syntax is [key]. In the case of the module, the key is an identifier, and the syntax is .key. Other than that they are nearly the same thing.
Editied from here
Related
how do you define dotted function?
i try this:
def myfunc.print(value)
print(value);
but it's said "Invalid syntax"
In python, and in many other languages, the "dot" syntax is a product of code organizational structure. So, X.Y tells python to look for Y inside of X. There are actually a few ways to do this. You can define a class which organizes a set of functions and properties within the class or its associated objects (as #Samwise's answer shows). You can also create a new file "myfunc.py", and have one of the functions defined in that file be def print(): pass - then when you import myfunc in another file you can access myfunc.print. In any case, the dot represents a "belonging" relationship, so you need to have your print function "belong" to the myfunc containing structure in some way.
Here's one way:
>>> class myfunc:
... print = print
...
>>> myfunc.print("foo")
foo
In this example, myfunc is actually a class, and print is a class attribute (which is initialized to point to the print function).
How do I get the exact class variable which is (in current scope) available under a given name? I want to write a function like this:
from my_module import ClassA # A subclass of my_other_module.BenevolentClass
from my_other_module import my_function
a = 'ClassA'
cls_var = my_function(a)
o = cls_var()
So that I could supply any string to my_function and so long as that string is available in the caller's namespace as a class name, it would produce the correct class much like if I copypasted the string directly to the code. The reason is that I need to supply class names to a complex object creation routine, but avoid eval when possible. My current implementation is like this:
def my_function(name):
if name in globals():
c = globals()[name]
# Actually a complex class whitelist
if issubclass(c, BenevolentClass):
return c
else:
raise ValueError(f'Potentially malicious class {name}')
But that apparently produces globals() from my_other_module, which is not what I want. I want all classes that are available at the exact line of code where my_function is called (which may be inside completely different module which is called from yet another one).
You can pass the global dict to my_function.
def my_function(name, g):
if name in g:
...
cls_var = my_function(a, globals())
I think I've found a solution. Not sure it is perfect, so I'd rather hear some comments before accepting my own answer.
import inspect
def my_function(name):
for frame in inspect.getouterframes(inspect.currentframe()):
c = None
if name in frame.frame.f_globals:
c = frame.frame.f_globals[name]
break
if c and issubclass(c, BenevolentClass):
return c
else:
raise ValueError(f'Potentially malicious class {name}')
As far as I understand it, inspect.getouterframes walks outwards along the call stack, and I can check globals on every step to see what's available. Neither local variables nor builtins are available in frame.f_globals, so it doesn't seem to have much potential for injecting malicious data.
I am new to python coming from Swift. In Swift I can create a new file and add code to an existing class using the extension key word. Does python have a similar way to do this or does all source code need to be in a single file?
I would like to do this to help organize my project.
In Python, functions are first-class citizens. This means that you can assign functions to names just like you assign other values. In particular, you can add a function to a class like this:
class Foo:
def foo(self):
print('foo')
def bar(self):
print('bar')
Foo.bar = bar
f = Foo()
f.foo()
f.bar()
Note that even though bar() is declared globally, it still must take at least one parameter. Traditionally, the first parameter of member functions is called self but this is only a convention and is not enforced by the language.
Python will also look in the same director as your base file when using the import or from keywords.
to build on Code-Apprentice's answer, you can also inherit easily from a class like this (if you wanted to extend the functionality of the list class:
class NewList(list): # inherit from the list class
#property
def sqrt_len(self):
return len(self) ** .5
nl = NewList([1, 2, 3, 4])
print(nl.sqrt_len) # prints "2.0" to stdout
You could then put newlist.py in the same directory as another .py and use import newlist or from newlist import NewList
A word of caution, make sure there isn't a name collision with your file and the name of another package that you want to use as python will import the files in the same directory first.
I am writing a Python package in which I have different Classes with a common method called map. That method always returns a function and is intended to be use inside a method of another package. Is there a way to lists all methods that are called map inside my package?
You're going to need to dip into a bit of reflection on this one. The steps you need are to load a reference a given module, grab the list of classes and then examine each class to make sure it has the method map:
import sys, inspect
def map_classes(module_name):
for name, obj in inspect.getmembers(sys.modules[module_name]):
if inspect.isclass(obj):
try:
if callable(getattr(obj, 'map')):
yield name
except AttributeError:
pass
This method will return a generator of all names of all classes within a module that have a map method. Note, if they have a map attribute, it will not return the name of the class.
You don't need the inspect package. Everything you need is built-in.
>>> import numpy as np
>>> for name, obj in np.__dict__.items():
... if hasattr(obj,"tolist"):
... print name, obj
Is it possible to dynamically name a function in a script as the name of the script? For example, if the script is called foo.py, is it possible to dynamically name a function in foo.py as foo? The reason I'm asking is that I import functions from several scripts and the naming convention is function_to_import = script - and to avoid any misspelling in the functions I'd like it to be dynamic. Thanks!
Yes, you can do something like
def main():
pass
globals()[__name__] = main
# if you no longer want the function to exist under its original name
del main
Messing with globals() is not generally recommended. I think it would make for clearer code to just bite the bullet and manually type out the name you need, but this is probably not the worst thing to do.
Note that this only changes the name that the function can be accessed with. It doesn't change the name of the underlying function object that you're accessing. If your code relies on that name, then you will have to do something more complicated.
There are multiple ways to assign a new name to a function, please note this would not change the name of the function, but the new name would also be pointing to that function.
Example 1 - While importing you can use as keyword to assign a new name, and then use it in the script using the new name
from foo import func as foo
foo()
Example 2 - You can assign the function to a new variable (a new name) and then use the new name to call it -
>>> def func(a):
... print("Hello")
...
>>> foo = func
>>> foo(1)
Hello
There may be more ways to do this.
You can use __file__ to get the filename and then assign the function to that file.
def my_function():
print "Hello, World!"
exec(__file__.split('.')[0] + " = my_function")
If you add this to your file, it will dynamically name the function my_function as the name of your file.