I'm writing an interpreter for an old in-game scripting language, and so need to compile dictionary that has the name of the command from the language matched up against the symbol for that function.
Now, I've already figured out here: How to call a function based on list entry?
...That you can call functions this way, and I know that you can use dir to get a list of strings of all functions in a module. I've been able to get this list, and using a regex, removed the built-in commands and anything else I don't actually want the script to be able to call. The goal is to sandbox here. :)
Now that I have the list of items that are defined in the module, I need to get the symbol for each definition.
For a more visual representation, this is the test module I want to get the symbol for:
def notify(stack,mufenv):
print stack[-1]
It's pulled in via an init script, and I am able to get the notify function's name in a list using:
import mufprims
import re
moddefs=dir(mufprims)
primsfilter=re.compile('__.+__')
primslist=[ 'mufprims.' + x for x in dir(mufprims) if not primsfilter.match(x) ]
print primslist
This returns:
['mufprims.notify']
...which is the exact name of the function I wish to find the symbol for.
I read over http://docs.python.org/library/symtable.html here, but I'm not sure I understand it. I think this is the key to what I want, but I didn't see an example that I could understand. Any ideas how I would get the symbol for the functions I've pulled from the list?
You want to get the function from the mufprims module by using getattr and the function name. Like so:
primslist=[getattr(mufprims, x) for x in dir(mufprims) if not primsfilter.match(x) ]
I thought I might add another possible suggestion for retrieving the functions of an object:
import inspect
# example using os.path
import os.path
results = inspect.getmembers(os.path, inspect.isroutine)
print results
# truncated result
[...,
('splitdrive', <function splitdrive at 0x1002bcb18>),
('splitext', <function splitext at 0x1002bcb90>),
('walk', <function walk at 0x1002bda28>)]
Using dir on the object would essentially give you every member of that object, including non-callable attributes, etc. You could use the inspect module to get a more controlled return type.
Related
So the question is basically:
I have a module called Fibo that has, for example, a function called fibonacci() that calculates a Fibonacci sequence. Since I want to use this in my program, I have to do this:
import Fibo
Fibo.fibonacci()
But this last line isn't an object with a method called fibonacci or actually it is?
Everything in Python is an object. If you're importing an object from a module, you will have the object in your current/actual module (i.e. program). You can create different namespaces and make your code more organized by using different files for your Python code. That's the advantage of using other modules and importing from it.
According to the Python documentation, it is better to simply avoid calling fibonacci a method and say that it is an attribute of an object, see:
method
A function which is defined inside a class body. [...]
attribute
A value associated with an object which is referenced by name using dotted expressions. For example, if an object o has an attribute a it would be referenced as o.a.
In the official documentation you can find the answer.
It boils down to this:
"When a module is first imported, Python searches for the module and if found, it creates a module object 1, initializing it."
So basically, yes, Fibo is an object.
I am stuck in resolving a problem using python. Problem is I have to pass a variable value of module(python_code1.py) to a different module(python_code2.py). Based on the variable value, need to do some calculation in the module python_code2.py and then need to capture output value in the same module(python_code1.py) for further calculations.
Below is the snapshot of my code logic :
python_code2.py
import python_code1
data = python_code1.json_data
'''
Lines of code
'''
output = "some variable attribues"
python_code1.py
import python_code2
json_data = {"val1": "abc3","val1": "abc3","val1": "abc3"}
input_data = python_code2.output
''''
Lines of code using input_data variable
'''''
when I execute python python_code1.py, this is giving error:
AttributeError: module 'python_code2' has no attribute 'output'
I feel like I am not doing it in write way, but considering my code complexity and lines of code, I have to use these 2 module method.
Putting your code at the top-level is fine for quick throw away scripts, but that's about all. The proper way to organize your code for anything non-trivial is to define functions, so you can pass values as arguments and get results as return value.
If there's only on script using those functions, you can keep them in the script itself.
If you have multiple scripts needing to use the same functions, move those functions to a module and import this module from your scripts.
Is there a way to perform a python import which is not atomic?
For instance, I have a file as follows:
# Filename: a.py
myvariable = 1
mylist = [1, 2, 3]
raise ImportError
donotimportthis = 5
I then have a separate file which does the following:
import a
a.myvariable == 1 # This is okay as it imported it
a.donotimportthis # <-- raise an exception as this is not imported.
I have a file which contains some python code, this follows the format of:
...variables...
import X
I do not have X installed nor do I want it however I do want the variables.
Note: This file is autogenerated not by me but by a tool whose version is frozen.
Two choices, in descending order of preference:
Change the autogeneration process. Instead of invoking proprietary_autogen_process, invoke custom_autogen_wrapper. This wrapper in turn first invokes the proprietary third-party tool, and then modifies the produced module source code by searching for the code that imports module X, and deletes everything after it.
This is relatively straightforward. You just need to take some care to not introduce false positives or false negatives by performing too loose (or too strict) matching of the import code. Ideally you’d use an AST rewriter but that’s probably overkill; a regular expression search for import X might work, although it will yield wrong results if this text appears inside a comment, string literal or inside a method which isn’t executed.
Generate a stub module X in a location where it will be found by the autogenerated module when importing the latter. I don’t recommend this because it’s tedious: You probably can’t just generate an empty module, since the autogenerated module will want to use X. You need to generate meaningful method stubs.
You can do specific imports with
from a import myvariable
EDIT: The above won't work if anything that is flat in the file raises an error. If you have no way to edit the imported file then I don't know if there is a (resonable) solution to this. Sorry didn't realise.
(an unreasonable solution would be to read in the file as text, slice it, and then run eval on it).
Or, as mentioned in the comments, put the stuff you don't want under
if __name__=="__main__":
<here>
Then it will only be invoked if you run the file directly.
What you can do is removing the donotimportthis variable at the end of the module, as follows: del donotimportthis. I hope it helps
I've noticed some functions are called using the var.func() format as in var1.split() while other functions are called using the func(var) format as in sorted(list1).
Here's a very simple program to illustrate the question. I've also noticed the same behavior with open and read functions.
str1 = "This is a string"
list1 = str1.split()
print str1.split(' ')
print sorted(list1)
I'm very new to programming so any help would be greatly appreciated!
Everything in python is an object. Thus when doing something like this:
s = "some string"
s is an str object and you can call all the str methods on it. You can also do things like this:
"some string".split()
and it will give you a list of splitted strings.
This difference has to do with issues of scope. Functions which can be called directly, such as sorted(list1) in your example above, are either builtin functions, or else defined at the top level of one of your imported libraries (for example when using from simpy import *, you can call test() directly to run the built in test suite for the simpy library). Functions which are accessed through the dot operator are functions which are defined for the particular data type that you are applying them to. Remember that each data type in python is an object, and therefore an instance of a class. Those functions, such as split() are defined in that data type's class definition. Additionally, to use the example of test() from the simpy library again, if you were to import a library with only import simpy, you would have to use simpy.test() to call that method.
from simpy import *
test()
vs
import simpy
simpy.test()
The first works because you've imported all methods and classes from the top level of the simpy library, whereas the second works because you've explicitly dived into the scope of the simpy library.
var.func() just means that the function belongs to the object.
For instance, x.sort(). lists (like x) have a function sort.
When you call func(var), func is not a function of lists.
For instance, sorted(x).
This isn't Python specific. You will see the same idea in other languages (e.g. Java).
In var.func() the func() is meant to be used with the var object.
e.g. split() on a string object but cannot use on a list
But func(var) is not confined to a single var object type. you can use it with any appropriate var object.
e.g. sorted() can be used with any iterable like lists, tuples, dicts...
Following TraxusIV's line of thought, I tried the following and it worked!
from string import split
str1 = "This is a string"
list1 = str1.split()
print split(str1)
print sorted(list1)
I am using iPython in command prompt, Windows 7.
I thought this would be easy to find, I searched and found directions on how to use the inspect package but it seems like the inspect package is meant to be used for functions that are created by the programmer rather than functions that are part of a package.
My main goal to to be able to use the help files from within command prompt of iPython, to be able to look up a function such as csv.reader() and figure out all the possible arguments for it AND all possible values for these arguements.
In R programming this would simply be args(csv.reader())
I have tried googling this but they all point me to the inspect package, perhaps I'm misunderstanding it's use?
For example,
If I wanted to see a list of all possible arguments and the corresponding possible values for these arguments for the csv.reader() function (from the import csv package), how would I go about doing that?
I've tried doing help(csv.reader) but this doesn't provide me a list of all possible arguments and their potential values. 'Dialect' shows up but it doesn't tell me the possible values of the dialect argument of the csv.reader function.
I can easily go to the site: https://docs.python.org/3/library/csv.html#csv-fmt-params and see that the dialect options are: delimiter, doublequote, escapechar, etc.. etc..but is there a way to see this in Python console?
I've also tried dir(csv.reader) but this isn't what I was looking for either.
Going bald trying to figure this out....
There is no way to do this generically, help(<function>) will at a minimum return you the function signature (including the argument names), Python is dynamically typed so you don't get any types and arguments by themselves don't tell you what the valid values are. This is where a good docstring comes in.
However, the csv module does have a specific function for listing the dialects:
>>> csv.list_dialects()
['excel', 'excel-tab', 'unix']
>>> help(csv.excel)
Help on class excel in module csv:
class excel(Dialect)
| Describe the usual properties of Excel-generated CSV files.
...
The inspect module is extremely powerful. To get a list of classes, for example in the csv module, you could go:
import inspect, csv
from pprint import pprint
module = csv
mod_string = 'csv'
module_classes = inspect.getmembers(module, inspect.isclass)
for i in range(len(module_classes)):
myclass = module_classes[i][0]
myclass = mod_string+'.'+myclass
myclass = eval(myclass)
# could construct whatever query you want about this class here...
# you'll need to play with this line to get what you want; it will failasis
#line = inspect.formatargspect(*inspect.getfullargspec(myclass))
pprint(myclass)
Hope this helps get you started!