How to find an object?

If I see a code or I am repairing defunct code I would need to know, where the specific object is located. I. e. in which library and under which class, etc. What are the ways to figure it out?

Can you show an example please?

I’d rather not guess at what problem you are asking for help with.

Modern source code editors, e.g. VS Code, let you right click and go to the definition etc. of a symbol.

1 Like

So in the past you were lost and you have to browse internet or ask someone?

I read the sources of the package that I have installed.

If you are not sure where the sources are you can just import the package and print the repr of the package. This includes the path of the .py file.

import pathlib
print(repr(pathlib))
1 Like

For example. I want to get build-in help on count() (method). If I type help(count) I receive an error. How can I know that it’s a method of the string and I should be calling the help via help(str.count)?

Thats good when you know the library. What about if you dont know the library?

How can I know that it’s a method of the string and I should be calling the help via help(str.count) ?

You stop coding in notepad.exe, and install a modern source code editor with “intellisense” instead.

VS_CODE_Python_intellisense_str.count

What about if you dont know the library?

Python’s namespace and import syntax mean that if a name is defined in a module or script, it was defined in the same module (in a parent scope of whereever it is referred to), or it’s a built in, or it was imported. In the latter case import statements require the library or sub module the name came from to be specified (*).

How else could the interpreter know where to fetch the code for a particular imported function from?

“Namespaces are one honking great idea – let’s do more of those!”

(*) At least by its import name. Tracking down the actual name of the library, e.g. on PyPi can be harder. For that you need to look in pyproject.toml, requirements.txt or setup.py and work it out.

Using modern IDEs is definitely a good thing. But the question of “how does python resolve imported code” really shouldn’t be dismissed. It’s a fair question that I think a lot of people would wonder, at LEAST for instructive purposes if not to help them build some tool. It would be nice to see a flow chart outlining how python resolves code when you make an import statement.

I know that when you make an import statement then python crawls the python path environment variable searching for a package with the same name as the import statement, but I’m not exactly sure how this works because the top level directory name may not match the import name. I’ve never understood how this difference gets resolved…

Seems like it’s described in details here: 5. The import system — Python 3.11.5 documentation, but there is indeed no flowchart.

1 Like

I’ve never thoroughly read through that documentation but I think you’re right that the answers to my questions (and probably the OPs?) are found there. I think the minor comment about the site package is also important in there.

So I think the answer to the OPs question would be something like: look at the top level import name for the package being imported, then, if it’s not a built in, then look at your python path and follow the linked to documentation to figure out where in the path your import got resolved. In most cases on my windows machine there is a directory with the same name as the import name in the site-packages folder for my python (virtual) environment and there are .py files in that directory (or in nested directories/sub-packages in that directory) which is where the code is being imported from.

2 Likes

Look at the __class__ attribute of something (or the type). If it’s not a module, then first find out from which module it came (or whether it’s a builtin). If it’s a module, then look at module.__file__.

>>> import uuid
>>> uuid.__class__ 
<class 'module'>
>>> uuid.__file__
'/Users/{my_login_name}/miniconda3/lib/python3.10/uuid.py'
>>> import pandas as pd
>>> pd.__file__
'/Users/{my_login_name}/miniconda3/lib/python3.10/site-packages/pandas/__init__.py'
1 Like

This works for the count case:

>>> help(''.count)
Help on built-in function count:

count(...) method of builtins.str instance
    S.count(sub[, start[, end]]) -> int

    Return the number of non-overlapping occurrences of substring sub in
    string S[start:end].  Optional arguments start and end are
    interpreted as in slice notation.

Also you can find out the type of an object, a string in this case, like this:

>>> type('')
<class 'str'>

@Juandev 's question is – what if he doesn’t know where count is coming from. But that question doesn’t really make sense in Python: you always know this!

In this example, you will never just see a naked ‘count’ function, but you will only see s.count() where (you can easily see or guess that) s is the name of some string. In the cases where you do come across a naked function (or class or whatever) name, it will always be inside some module, so it’s either some undefined name or it’s defined in that module itself or imported (with
from mystery_module.submodule import mystery_function
or some similar statement).

Names are always part of some namespace…
(Of course all this becomes a lot harder to trace when people start doing
from module import *
which should really be outlawed.)

3 Likes

It can be also one of built-in functions.

1 Like

The other example and again from the area of help is pass. If I type in help(pass)
I receive an error. So I should browse the Internet on what is pass and finally get the answer, that it is a keyword and in that case, you type in help("pass").

Before I learned bash. Looking for help was straightforward. You had a few ways how to get some manual pages (man *str*, info *str*, etc.) and that was it. Sometimes there were not man pages at all. With Python, you have to know what type of object you are dealing with and where it is located, to get the help.

I would have expected that you would have learnt about the few keywords used by python in a python tutorial. help() is not supposed to deal with keywords.

1 Like

Actually Python does help with keywords (Python 3.11.5) (and I actually only found this out while reading this thread!):

>>> help("pass")
The "pass" statement
********************

   pass_stmt ::= "pass"

"pass" is a null operation — when it is executed, nothing happens. It
is useful as a placeholder when a statement is required syntactically,
but no code needs to be executed, for example:

   def f(arg): pass    # a function that does nothing (yet)

   class C: pass       # a class with no methods (yet)

The thing is you do need to quote term, since you cannot call any function that takes a bare-bones keyword as argument. I wanted to write “you need to quote the term of course” but this may not be very obvious to people who just started learning Python as first programming language…

2 Likes

So actually help(help) could perhaps be improved a (tiny) bit:
Instead of

>>> help(help)
....
 |  Calling help() at the Python prompt starts an interactive help session.
 |  Calling help(thing) prints help for the python object 'thing'.

the following might be better:

....
 |  Calling help() at the Python prompt starts an interactive help session.
 |  Calling help(thing) prints help for the python object 'thing'. If 'thing'
 |  is a Python keyword like 'if', 'else', 'for', calling help("thing") with 
 |  the quoted keyword prints help.
3 Likes

Well, yes; the complaint was that the quotes are necessary. OP tried help(pass), which can’t work, because help is an ordinary Python function, and the REPL accepts Python code, not “commands”.

Imagine you saw someone else’s bash example like ls > /dev/null, and you didn’t understand what the > meant. So you tried man >, and info >, and got Bash syntax errors. It’s the same problem - except that in this case quoting doesn’t even help; as you say,

But then, the reason there are any man pages is because Linux derives from Unix, and Unix has existed for far longer than the Internet has been a useful research tool. Which brings me to…

Python, on the other hand, is barely any older than the World Wide Web, and really hit its stride (in my assessment) around the same time that Youtube appeared. So it’s hardly surprising that people are expected to look online for help. You don’t have to do searches, though. The documentation is all in one place, which is named very much like one would expect: https://docs.python.org .

Yes, it’s a little obnoxious that you seemingly have to understand that much about pass in order to be able to use it with the help command. But actually, you can just have the rule of always passing a string: help("str.count") works, and gives the same information as help(str.count). You can also access the help from the command line: python -m pydoc pass, or python -m pydoc str.count. And anyway, documentation can’t really teach you how to use tools. Reading the man pages won’t teach you how to write shell scripts, either.

2 Likes