I am trying to debug a python application using pudb, everything is fine and good except that it's not displaying the instance variables (which we access with self.xxx). It just displays 1 variable called self. And it's of the original class type.
Even if I tell it to show after calling str(self), it still only displays the object information.
If you see the code has created many variables like self.parser, self.groups and I am not able to view/inspect any of them.
Is there a way to view all the instance variables of the current class while debugging using pudb?
This is the expected behaviour, and has nothing to do with your debugger: you only have one name, self.
To see its contents you can use dir(self).
See inspect complex variable in python debugger, like pudb
The short way: Highlight the variable and press backslash \ to toggle between the "Expanded" view of a variable in the variable inspection panel.
In this case we would just highlight self, and press \, which is just the Python variable representing the instance of the class.
Alternatively, press ENTER to open the "Variable Inspection Options" menu where at the bottom you can see the "Expanded" option.
Related
I have a Click app called "DC" starting with click.Group cli(), which has many subcommands. I'm trying to produce a text file with a list of all commands, arguments, options, and help text as a convenient reference. How do I introspect a Click application?
I experimented using the API reference, but it's confusing. Some of Command's methods (like get_usage()) require a "context" object as the first arg, and I only know two ways to get one:
Be inside a command with #pass_context decorator. (Not always the case.)
Call click.get_current_context() to get the "current" context, which seems to be the one attached to the bottom-level command that is currently being executed.
That seemed to work:
from dc.__main__ import cli
current_ctx = click.get_current_context()
click.echo(cli.get_usage(current_ctx))
This prints the docstring from the cli() function. However, if I try to inspect the list of subcommands:
click.echo(cli.commands)
I get an empty dict. After more exploring, I finally managed to find my way to the real data by doing this:
current_ctx.find_root().command.commands
which returned a dict with all the top-level commands I expected to see.
Is that the preferred method?
Let's say I need to view the argument names in the editor, it's usually done with cmd/ctrl + p and here's the view:
However when I try the same in the debugger console, I only get *args, **kwargs
How to change this behavior to be able to see the actual argument names?
script path/Module name
Click the list to select a type of target to run. Then, in the corresponding field, specify the path to the Python script or the module name to be executed.
I'm wanting to go through a list of objects so that my PyCharm IDE knows what type each list item is:
For example, say I know that each item in a list is an class instance of type 'myClass' - how do I use this to cast my objects so that my ide can help with code completion?
for i in range(len(myList)):
myClass(myList[i]).myClassProperty .....
I know how to do it in Delphi (something like the above) but not in python.
Thanks
In PyCharm, you can use Type Hinting:
class Bar:
def __init__(self,bar):
self.bar = bar
def do_bar(self):
return self.bar
def foo(x):
for el in x: # type: Bar
el.do_bar()
bars = [Bar('hello'), Bar('World')]
foo(bars)
You can't get code completion similar to Java or C++ in dynamically typed, interpreted language.There is no casting, because you don't need it in python. A function works for a given object if it has needed methods implemented, type is irrelevant to the language at this point. It is good practice though to leave some runtime checks using isinstance, if you expect your argument to be e.g. a dict. Otherwise you will end up with many difficult bugs.
As for code completion in python there are two solutions I find useful. The best IDEs around here are probably PyCharm https://www.jetbrains.com/pycharm/ and PyDev the Eclipse Plugin http://www.pydev.org/manual_101_install.html. They provide some code completion.
The other is interactive console Jupyter http://jupyter.org/. As you write your code, you could execute it in chunks (cells) and easily see object methods or fields, using not the type information, but the object itself existing in memory. This is very good for data analysis or playing with framework you don't know well.
I have this chunk of code:
import click
#click.option('--delete_thing', help="Delete some things columns.", default=False)
def cmd_do_this(delete_thing=False):
print "I deleted the thing."
I would like to rename the option variable in --delete-thing. But python does not allow dashes in variable names. Is there a way to write this kind of code?
import click
#click.option('--delete-thing', help="Delete some things columns.", default=False, store_variable=delete_thing)
def cmd_do_this(delete_thing=False):
print "I deleted the thing."
So delete_thing will be set to the value of delete-thing
By default, click will intelligently map intra-option commandline hyphens to underscores so your code should work as-is. This is used in the click documentation, e.g., in the Choice example. If --delete-thing is intended to be a boolean option, you may also want to make it a boolean argument.
As gbe's answer says, click will automatically convert - in the cli parameters to _ for the python function parameters.
But you can also explicitly name the python variable to whatever you want. In this example, it converts --delete-thing to new_var_name:
import click
#click.command()
#click.option('--delete-thing', 'new_var_name')
def cmd_do_this(new_var_name):
print(f"I deleted the thing: {new_var_name}")
I have the following:
objects
__init__.py
define.py
define.py:
class Place:
def __init__(self,name,inhabitants):
self.name=name
self.inhabitants=inhabitants
myFunction.toStoreThings.on.db(name,inhabitants,'places')
def someUsefulFunction(self):
pass
If I run import objects, moon=objects.Place('Moon',[]), close the interpreter and open it again. I obviously loose the moon instance, but I have (u'Moon',u'[]') stored in the database. I already made __init__.py retrieve that information from the database and unstring it, but I'd also like it to instantiate 'Moon' as Moon=Place('Moon',[]) so I can use Moon.someUsefulFunction() or objects.Moon.someUsefulFunction() even after I close the interpreter. How can I achieve this?
I was able to do it like this:
__init__.py:
# myFunction() creates a dictionary `objdic` of the stuff in the database
# >>>objects.objdic
# {'places' : [['Moon',[]]]}
instancesdic={}
instancesdic['places']={}
instancesdic['places'][objdic['places'][0][0]]=Place(*objdic['places'][0])
Which gives
>>> objects.instancesdic
{'places': {'Moon': <objects.Place instance at 0x1b29248>}}
This way I can use
objects.instancesdic['places']['Moon'].someUsefulFunction()
Which is ok, but I really wanted objects.Moon.someUsefulFunction(). Any attempt to call that whole thing Moon results either in:
TypeError: 'str' object does not support item assignment
Or in just the key in the dictionary being changed to an instance, instead of the Moon instance being created.
You could use the setattr function to set module attributes on the objects module, or you could update globals within that module. So within your __init__.py you could do:
objDict = {obj[0]: Place(*obj) for obj in objdict['places']}
globals().update(objDict)
This will then let you do object.Moon, etc.
There is some danger to be aware of, though. If any of your objects have the same name as anything else already created in objects, they will overwrite those things. So if objects has a function called myFunc and then you create an object called myFunc, it could overwrite the function with the object. (Which will overwrite which depends on which order you do things in.)
For this reason, it's probably not a good idea to do this automatically in __init__.py. It can make sense to do this for ease of use in the interactive interpreter, but modifying globals in this way will get ugly if you use it in scripts. It might be a better idea to create a function called initGlobals or something, and then call that function to set up your interactive environment. If you put the code I showed above into such a function, then call it, it will set up the environment. This lets you separate the simple importing of the module from actually creating global objects from the db, because sometimes you might want to do one but not the other.