Inconsistency in python help('string') versus help(list)? - python

When I type help('string') in the python interpreter I get information about the string class. There,upper() is indicated as a function. Yet I can only call it as a method like "hi".upper() instead of upper("hi").
So one could assume that any method will be indicated as a function in the docstrings of the built in modules. Yet when I do help('list') , methods of the list class are indicated as methods in the docstrings!!
Why is this so? Only because the person who wrote the doctrings was inconsistent or that different people wrote it? Or do these methods(the ones called 'functions' versus the ones called 'methods' in the docstrings) actually have different properties?

When you searched for help('string'), you were looking for the docstrings of the string module. If you do help(str) or help('str') you'll get the docstrings of the str type, and here upper appears as a method!
As you can see here, the function upper from the string module is actually a function and not a method:
>>> upper('hi')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'upper' is not defined
>>> 'hi'.upper() # method from the str type
'HI'
>>> from string import upper
>>> upper('hi') # function from the string module
'HI'

You mean to do help('str'), not help('string'). str is a type, string is a module providing functions for working with strings.

You are creating an instance of that object and then calling help on that instance.
So these all work:
help(1)
help({})
help([])
help('')
help(dir)
help(help)
Help grabs the docstring for that instance, and gives it back to you.
When you create your own objects, you can put in useful docstrings or whatever you want.

There's nothing wrong with what you see.
>>> help('string')
Will show you the string module documentation. And it looks like there's an upper function inside:
>>> import string
>>> string.upper('hello')
'hello'
I'd say that this upper is the same that is called if you do:
>>> 'hello'.upper()
But I'm not sure.
Notice that a string '' is a str type not a string type. This means that you're probably looking for:
>>> help('str')
And here you'll see too the str.upper method.

This is because 'string' is a string. So is 'list'
To get a similar result for lists, try help([])

Related

What is Python's "Namespace" object?

I know what namespaces are. But when running
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('bar')
parser.parse_args(['XXX']) # outputs: Namespace(bar='XXX')
What kind of object is Namespace(bar='XXX')? I find this totally confusing.
Reading the argparse docs, it says "Most ArgumentParser actions add some value as an attribute of the object returned by parse_args()". Shouldn't this object then appear when running globals()? Or how can I introspect it?
Samwise's answer is very good, but let me answer the other part of the question.
Or how can I introspect it?
Being able to introspect objects is a valuable skill in any language, so let's approach this as though Namespace is a completely unknown type.
>>> obj = parser.parse_args(['XXX']) # outputs: Namespace(bar='XXX')
Your first instinct is good. See if there's a Namespace in the global scope, which there isn't.
>>> Namespace
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'Namespace' is not defined
So let's see the actual type of the thing. The Namespace(bar='XXX') printer syntax is coming from a __str__ or __repr__ method somewhere, so let's see what the type actually is.
>>> type(obj)
<class 'argparse.Namespace'>
and its module
>>> type(obj).__module__
'argparse'
Now it's a pretty safe bet that we can do from argparse import Namespace and get the type. Beyond that, we can do
>>> help(argparse.Namespace)
in the interactive interpreter to get detailed documentation on the Namespace class, all with no Internet connection necessary.
It's simply a container for the data that parse_args generates.
https://docs.python.org/3/library/argparse.html#argparse.Namespace
This class is deliberately simple, just an object subclass with a readable string representation.
Just do parser.parse_args(...).bar to get the value of your bar argument. That's all there is to that object. Per the doc, you can also convert it to a dict via vars().
The symbol Namespace doesn't appear when running globals() because you didn't import it individually. (You can access it as argparse.Namespace if you want to.) It's not necessary to touch it at all, though, because you don't need to instantiate a Namespace yourself. I've used argparse many times and until seeing this question never paid attention to the name of the object type that it returns -- it's totally unimportant to the practical applications of argparse.
Namespace is basically just a bare-bones class, on whose instances you can define attributes, with a few niceties:
A nice __repr__
Only keyword arguments can be used to instantiate it, preventing "anonymous" attributes.
A convenient method to check if an attribute exists (foo in Namespace(bar=3) evaluates to False)
Equality with other Namespace instances based on having identical attributes and attribute values. (E.g. ,Namespace(foo=3, bar=5) == Namespace(bar=5, foo=3))
Instances of Namespace are returned by parse_args:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('bar')
args = parser.parse_args(['XXX'])
assert args.bar == 'XXX'

How to check the type of an object against the type "function"

I am wiriting a script in which I would like to verify if a given argumente to a function is itself a function. I have checked in the IDLE the type() of that argument.
Let us assume that the argumente is called a and that I know that a is a function.
When I type type(a) in the Shell, this gets printed:
<class 'function'>
But if I try to type this:
type(add) == function
It gives me a NameError: name 'function' is not defined
(That was not my only attempt, but if I put them all here this will get too long)
I think I understand that part, because I think function is not a keyword like int or float, which lets me do conditionals like type(3) == int
But, knowing this, how can I check if something is from a given built-in type, if that type does not have a specific keyword (or maybe, those keywords are not that well-known)
Thanks in advance.
You can use the isinstance built-in to check if the type of a variable conforms to a type of a function. Unfortunately, as there is no short hand to create a function type just like int you can import types and check with types.FunctionType
>>> import types
>>> isinstance(add, types.FunctionType)
True
you can also import isfunction from inspect to perform the same check
import inspect
inspect.isfunction(add)
from inspect import isfunction
isfunction(a)

Python: uniquely identify a function from a module

I am not really a programmer but a computational statistician, so I may understand complex algorithms but not simple programming constructs.
My original problem is to check within a function if a module function is callable. I looked around and decided to go for a try (call function) - except (import module) to make it simple. I'd love to search sys.mod for this but I am running in some identifiability problems.
My current problem is that there are many ways of importing a function from a module: import module will define the function as module.function but from module import function will define it as function. Not to mention from module import function as myfunction. Therefore the same function can be called in several different ways.
My question is: is there a unique "signature" for a function that can be traced if the module is loaded? It would be fantastic to have the actual call alias to it.
ps besides: mod is mathematical function and sys.mod returns a list of loaded modules, but python (2.7) does not complain when you shadow the built-in mod function by doing the following, from sys import mod. I find this a bit awkward - is there any way to avoid this sort of shadowing programatically?
My original problem is to check within a function if a module function is callable.
By definition, all functions are callable. This will test if an object is callable: http://docs.python.org/library/functions.html#callable
Therefore the same function can be called in several different ways.
Yes, but it will be the same object. You can just use f is g to test if f and g are the same object.
Update: Why would you need to use a unique ID? Seriously, don't do this. You have is for identity tests, and the __hash__ method to define the hash function applicable.
It would be fantastic to have the actual call alias to it.
Not sure at all what you mean, but I think you just want it to always be one object. Which it is already.
mod is mathematical function and sys.mod returns a list of loaded modules, but python (2.7) does not complain to from sys import mod. I find this a bit awkward?
Then don't do that. You know about the import ... as syntax. Also mod is not by default in the global namespace (the operator % is for that).
Finally, python does complain about your import line:
>>> from sys import mod
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cannot import name mod
(Thanks to kindall for pointing this out).
Assume I have a module with the following:
def foo(): pass
bar = foo
You can easily see that they're the same functions by using is or id():
>>> import demo
>>> from demo import *
>>> demo.foo is foo
True
>>> id(demo.foo) == id(foo)
True
>>> demo.bar is foo
True
They all refer to the same code object, it's just stored under different names in the scope dictionary.
# define modulus f
def mod(a,b):
return b % a
print mod(5,2)
alias:
modulus=mod
print modulus(5,2)
this is pretty pythonic construct, and it is pretty intuitive for mathematicians
different ways of import serve to help you place a function into different "name space" for later use in your program, sometimes you wish to use a function a lot so you choose variant that is shorter to write.
you can also do something like:
myat=math.atanh
to make alias in another "name space"
and use it as:
myat(x)
as it would use math.atanh(x) - becomes shorter to write
Typical programmers approach would be define all you want to use and then use it. What you are trying in my belief is to do it "lazy" => import module when you need a function. That is why you wish to know if function is "callable".
Python is not functional programming language (e.g. like haskel) so that you can load or refer "on demand".
hope this helps.

Get built-in function from the function name

How can I get the int(), float(), dict(), etc. callables from their names? For example, I'm trying to save Python values to xml and storing the variable type as a string. Is there a way to get the callable from the string when converting from string back to the Python type?
Normally I would do something like getattr(myobj, 'str'), but there is no module to use as the first argument for these built-in conversion functions. I've also tried getattr(object, 'str'), but this doesn't work either since these functions are not part of the base 'object' type, merely globals to the language.
Normally I would do something like getattr(myobj, 'str'), but there is no module to use as the first argument for these built-in conversion functions.
Wrong, there is:
import __builtin__
my_str = getattr(__builtin__, "str")
(In Python 3.x: import builtins)
You don't need to import anything
vars(__builtins__)['dict']
vars(__builtins__)['float']
vars(__builtins__)['int']
etc.
One quick way is to invoke it from the __builtin__ module. For example
>>> import __builtin__
>>> __builtin__.__dict__['str'](10)
'10'

Python's c api and __add__ calls

I am writing a binding system that exposes classes and functions to python in a slightly unusual way.
Normally one would create a python type and provide a list of functions that represent the methods of that type, and then allow python to use its generic tp_getattro function to select the right one.
For reasons I wont go into here, I can't do it this way, and must provide my own tp_getattro function, that selects methods from elsewhere and returns my own 'bound method' wrapper. This works fine, but means that a types methods are not listed in its dictionary (so dir(MyType()) doesn't show anything interesting).
The problem is that I cannot seem to get __add__ methods working. see the following sample:
>>> from mymod import Vec3
>>> v=Vec3()
>>> v.__add__
<Bound Method of a mymod Class object at 0xb754e080>
>>> v.__add__(v)
<mymod.Vec3 object at 0xb751d710>
>>> v+v
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'mymod.Vec3' and 'mymod.Vec3'
As you can see, Vec3 has an __add__ method which can be called, but python's + refuses to use it.
How can I get python to use it? How does the + operator actually work in python, and what method does it use to see if you can add two arbitrary objects?
Thanks.
(P.S. I am aware of other systems such as Boost.Python and SWIG which do this automatically, and I have good reason for not using them, however wonderful they may be.)
Do you have an nb_add in your type's number methods structure (pointed by field tp_as_number of your type object)?

Categories

Resources