import pickle
class A:
pass
pickle.dumps(B().__reduce__())
yields
(<function _reconstructor at 0x1010143b0>, (<class '__main__.B'>, <class 'object'>, None))
What is this function "_reconstructor". It's neither B, B.__init__, nor B.__new__ as I expected.
I have to make 2 changes to get that result:
Change the name of your class from A to B.
Remove the outer pickle.dumps() call.
In any case, pickle is free to do anything it likes to reconstruct the object ;-) In this case, you can find the _reconstructor() function in Lib/copyreg.py.
Related
A short inheritance example:
class Person:
def __init__(self, fname, lname):
self.firstname = fname
self.lastname = lname
class Student(Person):
def __init__(self, fname, lname):
super().__init__(fname, lname)
print(type(super()))
Now entering Student("test", "name") will result in <class 'super'> being printed to the console. I'm not familiar with this format. When I do type(int) I see the type as type, not as <class 'int'>. Can someone explain what is going on here?
If you take a look at the docs,
Return a proxy object that delegates method calls to a parent or sibling class of type.
This proxy object is of type super; assuming super_object = super(), then type(super_object) returns a type object that describes the class to which all super objects belong to. Just like type(0) returns a type object that describes integers. <class 'int'> is how this type object prints itself. Fun fact: you already know this object.
>>> int
<class 'int'>
>>> type(0)
<class 'int'>
>>> type(0) == int
True
Note that in Python, constructor for a class is the type object itself. So when you write int(), you are constructing a new object of type int, just like when you write Student("test", "name"), you are constructing a new object of type Student. And so it is with super as well:
>>> type(super()) == super
True
To round out this answer, I will note something very, very obvious, but possibly worth mentioning here just in case. A variable might, and often does, differ from how its value is displayed. When you say
x = 3
print(x)
you don't expect the answer to be x, but 3, because that is the way the value inside x displays itself (via int.__str__ method). int is just another variable, one that happens to contain the integer type object. This type object displays itself as <class 'int'>, not int. int is just a variable name.
>>> my_shiny_number = int
>>> my_shiny_number()
0
>>> type(my_shiny_number())
<class 'int'>
And conversely (and please never ever do this in real code, this is for illustration purposes only):
>>> int = str
>>> int()
''
>>> type(int())
<class 'str'>
In Python, we can define a class and print it as such:
class a:
num = 1
b = a()
print(b)
And we would get the output:
<class '__main__.a'>
I'm trying to identify unique classes, and I have some classes with longer paths. I would like to extract the "class path", or __main__.a in the case above. For example, if I print some longer class I would get:
<class 'django_seed.tests.Game'>
<class 'django_seed.tests.Player'>
<class 'django_seed.tests.Action'>
And I would like to extract:
'django_seed.tests.Game'
'django_seed.tests.Player'
'django_seed.tests.Action'
Since I can cast <class 'django_seed.tests.Game'> to a string, I can substring it quite easily with '<class 'django_seed.tests.Game'>'[8:-2], but I'm sure there must be a cleaner way. Thanks!
The __module__ attribute can be used to access the "path" of a class (where it was defined) and the __name__ attribute returns the name of the class as a string
print(f'{YourClass.__module__}.{YourClass.__name__}')
You can use inspect:
import inspect
print((inspect.getmodule(a).__file__))
sup = super(B, self) and sup2 = super(B, B) have indistinguishable representations, they both look like this:
<super: <class 'B'>, <B object>>
while super(B, self).spam gives a bound method, super(B, B) only works with class methods, so super(B, B).cls_spam(), like demonstrated below. You can't use it for regular methods, you get a normal function:
class A:
#classmethod
def cls_spam(cls):
print('A.cls_spam: cls =', cls)
def spam(self):
print('A.spam: self =', self)
class B(A):
def call_spam(self):
sup = super(B, self)
print('B.call_spam: sup =', sup)
print('B.call_spam: sup.spam =', sup.spam)
print('B.call_spam: sup.cls_spam =', sup.cls_spam)
sup.spam()
sup.cls_spam()
sup2 = super(B, B)
print('B.call_spam: sup2 =', sup2)
print('B.call_spam: sup2.css_spam =', sup2.cls_spam)
# can't call sup2.spam(), not without giving it self explicitly
sup2.cls_spam()
The following interactive session illustrates:
>>> b = B()
>>> b.call_spam3()
B.call_spam: sup = <super: <class 'B'>, <B object>>
B.call_spam: sup.spam = <bound method A.spam of <__main__.B object at 0x108830b50>>
B.call_spam: sup.cls_spam = <bound method A.cls_spam of <class '__main__.B'>>
A.spam: self = <__main__.B object at 0x108830b50>
A.cls_spam: cls = <class '__main__.B'>
B.call_spam: sup2 = <super: <class 'B'>, <B object>>
B.call_spam: sup2.css_spam = <bound method A.cls_spam of <class '__main__.B'>>
A.cls_spam: cls = <class '__main__.B'>
super() is a complicated subject, if the demonstrated above behavior is documented understanding it would help me a lot.
Using Python 3.5.3,Debian GNU/Linux 9.11 (stretch)
super() is meant to be useful both in class methods and in regular methods. In a classmethod there is no instance, you only have access to the class, so the second argument to super() accepts either an instance or a class. That at least is covered in the documentation for super():
If the second argument is an object, isinstance(obj, type) must be true. If the second argument is a type, issubclass(type2, type) must be true (this is useful for classmethods).
Bold emphasis mine.
Now, the primary task super() has to perform is to search for attributes along the Method Resolution Order (MRO) list of classes, given a starting point. The starting point is the first argument, but the MRO has to be taken from the second argument; if you use super() in class Foo, you can't know at that time if Foo might have been subclassed, which can alter the MRO of the second argument. So, for this purpose, super() tracks two pieces of information:
The class you want to use as a starting point for the search (the first argument)
The class from which the MRO is taken (the type of the second argument if it is an instance, or just the second argument, if it is a class).
There is also a 3rd piece of information, the instance or class to which attributes are bound, when you do an attribute lookup. That's simply the second argument itself, so either an instance or class. The repr() output reflects just the first two values, in large part because those are 'hidden' in that super(), without arguments, gets its arguments from the context and so you can't, as easily see what the starting point is, or what the MRO source is, but you can much more easily see the first argument to the method (so self or cls).
If you want to distinguish between your two super() instances, you can instead look at the __self__ attribute, which represents that 3rd piece of information:
>>> sup = super(B, b)
>>> sup.__self__
<__main__.B object at 0x108b4c520>
>>> sup2 = super(B, B)
>>> sup2.__self__
<class '__main__.B'>
The other two pieces of information you do see in the repr() output are the __thisclass__ and __self_class__ attributes, respectively:
>>> sup.__thisclass__, sup.__self_class__
(<class '__main__.B'>, <class '__main__.B'>)
This is easier to spot when you use a different class as the first argument:
>>> sup_a = super(A, b)
>>> sup_a
<super: <class 'A'>, <B object>>
>>> sup_a.__thisclass__, sup_a.__self_class__
(<class '__main__.A'>, <class '__main__.B'>)
I am learning a tutorial on python.It is explaining how functions are first class objects in Python.
def foo():
pass
print(foo.__class__)
print(issubclass(foo.__class__,object))
The output that I get for the above code is
<type 'function'>
True
This program is supposed to demonstrate that functions are first class objects in python? My questions are as follows.
How does the above code prove that functions are fist class objects?
What are the attributes of a first class object?
what does function.__class__ signify? It returns a tuple <type,function> which doesn't mean much?
Here's what Guido says about first class objects in his blog:
One of my goals for Python was to make it so that all objects were "first class." By this, I meant that I wanted all objects that could be named in the language (e.g., integers, strings, functions, classes, modules, methods, etc.) to have equal status. That is, they can be assigned to variables, placed in lists, stored in dictionaries, passed as arguments, and so forth.
The whole blog post is worth reading.
In the example you posted, the tutorial may be making the point that first class objects are generally descendents of the "object" class.
First-class simply means that functions can be treated as a value -- that is you can assign them to variables, return them from functions, as well as pass them in as a parameter. That is you can do code like:
>>> def say_hi():
print "hi"
>>> def say_bye():
print "bye"
>>> f = say_hi
>>> f()
hi
>>> f = say_bye
>>> f()
bye
This is useful as you can now assign functions to variables like any ordinary variable:
>>> for f in (say_hi, say_bye):
f()
hi
bye
Or write higher order functions (that take functions as parameters):
>>> def call_func_n_times(f, n):
for i in range(n):
f()
>>> call_func_n_times(say_hi, 3)
hi
hi
hi
>>> call_func_n_times(say_bye, 2)
bye
bye
About __class__ in python tells what type of object you have. E.g., if you define an list object in python: a = [1,2,3], then a.__class__ will be <type 'list'>. If you have a datetime (from datetime import datetime and then d = datetime.now(), then the type of d instance will be <type 'datetime.datetime'>. They were just showing that in python a function is not a brand new concept. It's just an ordinary object of <type 'function'>.
You proved that functions are first class objects because you were allowed to pass foo as an argument to a method.
The attributes of first class objects was nicely summarised in this post: https://stackoverflow.com/a/245208/3248346
Depending on the language, this can
imply:
being expressible as an anonymous literal value
being storable in variables
being storable in data structures
having an intrinsic identity (independent of any given name)
being comparable for equality with other entities
being passable as a parameter to a procedure/function
being returnable as the result of a procedure/function
being constructible at runtime
being printable
being readable
being transmissible among distributed processes
being storable outside running processes
Regarding your third question, <type 'function'> isn't a tuple. Python's tuple notation is (a,b), not angle brackets.
foo.__class__ returns a class object, that is, an object which represents the class to which foo belongs; class objects happen to produce descriptive strings in the interpreter, in this case telling you that the class of foo is the type called 'function'. (Classes and types are basically the same in modern Python.)
It doesn't mean a whole lot other than that, like any other object, functions have a type:
>>> x = 1
>>> x.__class__
<type 'int'>
>>> y = "bar"
>>> y.__class__
<type 'str'>
>>> def foo(): pass
...
>>> foo.__class__
<type 'function'>
Regarding your comment to #I.K.s answer, f_at_2() in the following would be the method.
def f_at_2(f):
return f(2)
def foo(n):
return n ** n
def bar(n):
return n * n
def baz(n):
return n / 2
funcs = [foo, bar, baz]
for f in funcs:
print f.func_name, f_at_2(f)
...
>>>
foo 4
bar 4
baz 1
>>>
A method is a function of/in a class, but the concept also applies to a function (outside of a class). The functions (as objects) are contained in a data structure and passed to another object.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is there a function in Python to print all the current properties and values of an object?
In interactive python sessions I make a lot of use of the dir function, to get a sense of an object's structure. Unfortunately, dir only shows the names of attributes, not their values, so it is nowhere near as informative as it could be. Furthermore, dir's print out makes no attempt to format the output for ease of reading (IOW: dir don't do no stinkin' pretty-print).
Where can I find an "off-the-shelf" data-inspection utility that is more informative, and better formatted, dir?
For example, a more useful alternative to dir would print the values (suitably formatted, as needed) associated with each attribute, and would format this output for easy reading. For attributes whose values are callable, it would print their signatures and/or the first lines of their docstrings.
Thanks!
Try the inspect module, which can give you all sorts of things, including the original source code for a function, stack frames and more:
>>> class Foo:
... def __init__(self, a, b, c):
... self.a = a
... self.b = b
... self.c = c
... def foobar(self):
... return 100
...
>>> f = Foo(50, 'abc', 2.5)
>>> import inspect
>>> inspect.getmembers(f)
[('__doc__', None), ('__init__', <bound method Foo.__init__ of <__main__.Foo instance at 0x7f0d76c440e0>>), ('__module__', '__main__'), ('a', 50), ('b', 'abc'), ('c', 2.5), ('foobar', <bound method Foo.foobar of <__main__.Foo instance at 0x7f0d76c440e0>>)]
>>>
>>> def add5(x):
... """adds 5 to arg"""
... return 5 + x
...
>>> inspect.getdoc(add5)
'adds 5 to arg'
>>> # What arguments does add5 take?
>>> inspect.getargspec(add5)
ArgSpec(args=['x'], varargs=None, keywords=None, defaults=None)
>>> # Format that nicely...
>>> inspect.formatargspec(inspect.getargspec(add5))
'((x,), None, None, None)'
>>>
If , by "object's structure" , you mean the instance attributes of the object, note that dir(something) calls something.__dir()__ if a user-defined method with name __dir__() exists, otherwise it inspects something.__dict__ and the type of something (I suppose it then calls the type's __dir__() or inspects the type's __dict__ )
Hence I believe that the instance attributes of an objects are given by its __dict__ attribute.
But some objects have no instance attributes, for example integers.
So, I think that if you test the existence of the __dict__ attribute of an object and, if it exists, obtaining its value will give you what you need to obtain : not only the names of the attributes but the objects so named.
Since you ask for formating of the output, I give this example with cPickle (a module is an object, as everything in Python)
import cPickle
for name,obj in cPickle.__dict__.iteritems() :
print '%-25s --> %r' % (name, obj)
result
load --> <built-in function load>
PicklingError --> <class 'cPickle.PicklingError'>
__version__ --> '1.71'
UnpickleableError --> <class 'cPickle.UnpickleableError'>
dump --> <built-in function dump>
__builtins__ --> <module '__builtin__' (built-in)>
Unpickler --> <built-in function Unpickler>
compatible_formats --> ['1.0', '1.1', '1.2', '1.3', '2.0']
BadPickleGet --> <class 'cPickle.BadPickleGet'>
__package__ --> None
dumps --> <built-in function dumps>
UnpicklingError --> <class 'cPickle.UnpicklingError'>
PickleError --> <class 'cPickle.PickleError'>
HIGHEST_PROTOCOL --> 2
__name__ --> 'cPickle'
loads --> <built-in function loads>
Pickler --> <built-in function Pickler>
__doc__ --> 'C implementation and optimization of the Python pickle module.'
format_version --> '2.0'
.
There's also the function help() that brings documentation you are searching for.
Check out pprint
from pprint import pprint
pprint(object_you_want_to_see)