Advanced Function and Class Concepts in Python
Table of Contents:

Functions
Function inside a function
This is an easy concept almost any programming language has:
def count():
def count_to(n):
for i in range(1, n+1):
print(i)
count_to(3)
count()
Out:
1
2
3
Closure
A closure is very similar to simple nested function, except it references one or more variables from its enclosing scope.
def count():
n=3
def count_to(n):
for i in range(1, n+1):
print(i)
count_to(n)
count()
Out:
1
2
3
Methods and functions difference
Python built-in type() can provide good debugging information.
Example:
class C:
def __init__(self, name, age):
self.name = name
self.age = age
def m1(self, x):
print("Excellent {}".format(x))
@classmethod
def m2(cls, x):
print("Excellent cls {}".format(x))
@staticmethod
def m3(x):
print("Excellent static {}".format(x))
ci=C("John", 36)
L=dir(C) # c is a class
for i in L:
print("C::", i, type(eval('ci.'+i)))
Output:
C:: m1 <class 'method'>
C:: m2 <class 'method'>
C:: m3 <class 'function'>
On the other hand we know that anything we define out-of-the-class with def keyword is a function:
def foo():
pass
type(foo) # function
Function decorators
Function decorators allow you to execute code before and after the function itself. Here is a basic example.
def decorator1(func):
def stub():
print("before f1")
func()
print("after f1")
return stub
@decorator1
def f1():
print("f1")
f1()
Out:
before f1
f1
after f1
Partials
Partials are imported from functools. They enable you to create new kind of functions or classes of type (functools.partial).
This new function will have some implicit parameters.
The partial is like a function without a body, entirely dependent on the host function being specified, but with some parameter predefined.
Example:
from functools import partial
def multiply(x,y): return x * y
# create a new kind of function that multiplies by 2
fdouble = partial(multiply,2)
fdouble(4)
Out:
8
type(fdouble)
Out:
functools.partial
Classes
Partials
Partials are not just functions, they can help us define a class:
from functools import partial
class C:
def __init__(self, a,b):
pass
c = C(1,2)
print(type(c))
cp = partial(C,1)
print(cp)
print(type(cp))
def fun1(a,b,c):
print(a,b,c)
return a+b+c
fun2 = partial(fun1,c=3)
fun2(4,5)
print(fun2)
print(type(fun2))
Out:
<class '__main__.C'>
functools.partial(<class '__main__.C'>, 1)
<class 'functools.partial'>
4 5 3
functools.partial(<function fun1 at 0x00000298EA515708>, c=3)
<class 'functools.partial'>
Print public methods of a class
You can use inspect module:
class SimulationApi(object):
def hello(self):
return "Hi"
def echo(self, string):
return string
def get_foo(self):
return self.foo
def __init__(self):
self.foo = 50
import inspect
inspect.getmembers(SimulationApi)
Out:
[('__class__', type),
('__delattr__', <slot wrapper '__delattr__' of 'object' objects>),
('__dict__',
mappingproxy({'__module__': '__main__',
'hello': <function __main__.SimulationApi.hello(self)>,
'echo': <function __main__.SimulationApi.echo(self, string)>,
'get_foo': <function __main__.SimulationApi.get_foo(self)>,
'__init__': <function __main__.SimulationApi.__init__(self)>,
'__dict__': <attribute '__dict__' of 'SimulationApi' objects>,
'__weakref__': <attribute '__weakref__' of 'SimulationApi' objects>,
'__doc__': None})),
('__dir__', <method '__dir__' of 'object' objects>),
('__doc__', None),
('__eq__', <slot wrapper '__eq__' of 'object' objects>),
('__format__', <method '__format__' of 'object' objects>),
('__ge__', <slot wrapper '__ge__' of 'object' objects>),
('__getattribute__', <slot wrapper '__getattribute__' of 'object' objects>),
('__gt__', <slot wrapper '__gt__' of 'object' objects>),
('__hash__', <slot wrapper '__hash__' of 'object' objects>),
('__init__', <function __main__.SimulationApi.__init__(self)>),
('__init_subclass__', <function SimulationApi.__init_subclass__>),
('__le__', <slot wrapper '__le__' of 'object' objects>),
('__lt__', <slot wrapper '__lt__' of 'object' objects>),
('__module__', '__main__'),
('__ne__', <slot wrapper '__ne__' of 'object' objects>),
('__new__', <function object.__new__(*args, **kwargs)>),
('__reduce__', <method '__reduce__' of 'object' objects>),
('__reduce_ex__', <method '__reduce_ex__' of 'object' objects>),
('__repr__', <slot wrapper '__repr__' of 'object' objects>),
('__setattr__', <slot wrapper '__setattr__' of 'object' objects>),
('__sizeof__', <method '__sizeof__' of 'object' objects>),
('__str__', <slot wrapper '__str__' of 'object' objects>),
('__subclasshook__', <function SimulationApi.__subclasshook__>),
('__weakref__', <attribute '__weakref__' of 'SimulationApi' objects>),
('echo', <function __main__.SimulationApi.echo(self, string)>),
('get_foo', <function __main__.SimulationApi.get_foo(self)>),
('hello', <function __main__.SimulationApi.hello(self)>)]
Your methods (the methods you like to get info) are also the
SimulationApiclass dictionary dict.
You can get the full code for your echo() function like this:
import inspect
lines = inspect.getsource(SimulationApi.echo)
print(lines)
def echo(self, string):
return string
Printing class types
Example:
class test(object):
def __init__(self):
self.a = 1
self.b = "abc"
test_obj = test()
print(vars(test_obj))
for k, v in vars(test_obj).items():
print('variable is {0}: and variable value is {1}, of type {2}'.format(k,v, type(v)))
Out:
{'a': 1, 'b': 'abc'}
variable is a: and variable value is 1, of type <class 'int'>
variable is b: and variable value is abc, of type <class 'str'>
Get class variables without instantiating
It is possible to do that using the type keyword in Python. There you have the example like this:
class X:
a = 1
X = type('X', (object,), dict(a=1))
print(X)
Out:
<class '__main__.X'>
What is class dict?
Class dict is a mappingproxy. A mappingproxy is simply a dict with no __setattr__ method.
You can check out and refer to this code.
from types import MappingProxyType
d={'key': "value"}
m = MappingProxyType(d)
print(type(m)) # <class 'mappingproxy'>
m['key']='new' #TypeError: 'mappingproxy' object does not support item assignment
mappingproxy is since Python 3.3. The following code shows dict types:
class C:pass
ci=C()
print(type(C.__dict__)) #<class 'mappingproxy'>
print(type(ci.__dict__)) #<class 'dict'>
How to add property to a class dynamically?
class C:
def __init__(self):
self._x=None
def g(self):
return self._x
def s(self, x):
self._x = x
def d(self):
del self._x
def s2(self,x):
self._x=x+x
x=property(g,s,d)
c = C()
c.x="a"
print(c.x)
C.x=property(C.g, C.s2)
C.x=C.x.deleter(C.d)
c2 = C()
c2.x="a"
print(c2.x)
Out:
a
aa
getattr(object, 'x')is completely equivalent toobject.x.
Appendix
Printing
Python dir command can’t provide you all. It’s just a list of what you have inside a module.
How to provide also the type of the object?
import matplotlib.pyplot as plt
# type(plt) # module
# dir(plt) # what is in the plot object
d=dir(plt)
def dirtype(d):
for i in d:
print(i, type(eval('plt.'+i)))
dirtype(d)
Out:
Annotation <class 'type'>
Arrow <class 'type'>
Artist <class 'type'>
AutoLocator <class 'type'>
Axes <class 'type'>
Button <class 'type'>
Circle <class 'type'>
Figure <class 'type'>
FigureCanvasBase <class 'type'>
FixedFormatter <class 'type'>
FixedLocator <class 'type'>
FormatStrFormatter <class 'type'>
Formatter <class 'type'>
FuncFormatter <class 'type'>
GridSpec <class 'type'>
IndexLocator <class 'type'>
Line2D <class 'type'>
LinearLocator <class 'type'>
Locator <class 'type'>
LogFormatter <class 'type'>
LogFormatterExponent <class 'type'>
LogFormatterMathtext <class 'type'>
LogLocator <class 'type'>
MaxNLocator <class 'type'>
MultipleLocator <class 'type'>
Normalize <class 'type'>
NullFormatter <class 'type'>
NullLocator <class 'type'>
Number <class 'abc.ABCMeta'>
PolarAxes <class 'type'>
Polygon <class 'type'>
Rectangle <class 'type'>
ScalarFormatter <class 'type'>
Slider <class 'type'>
Subplot <class 'type'>
SubplotTool <class 'type'>
Text <class 'type'>
TickHelper <class 'type'>
Widget <class 'type'>
_INSTALL_FIG_OBSERVER <class 'bool'>
_IP_REGISTERED <class 'function'>
__builtins__ <class 'dict'>
__cached__ <class 'str'>
__doc__ <class 'str'>
__file__ <class 'str'>
__loader__ <class '_frozen_importlib_external.SourceFileLoader'>
__name__ <class 'str'>
__package__ <class 'str'>
__spec__ <class '_frozen_importlib.ModuleSpec'>
_auto_draw_if_interactive <class 'function'>
_backend_mod <class 'module'>
_get_running_interactive_framework <class 'function'>
_interactive_bk <class 'list'>
_log <class 'logging.Logger'>
_pylab_helpers <class 'module'>
_setp <class 'function'>
_setup_pyplot_info_docstrings <class 'function'>
_show <class 'function'>
acorr <class 'function'>
angle_spectrum <class 'function'>
annotate <class 'function'>
arrow <class 'function'>
autoscale <class 'function'>
autumn <class 'function'>
axes <class 'function'>
axhline <class 'function'>
axhspan <class 'function'>
axis <class 'function'>
axvline <class 'function'>
axvspan <class 'function'>
bar <class 'function'>
barbs <class 'function'>
barh <class 'function'>
bone <class 'function'>
box <class 'function'>
boxplot <class 'function'>
broken_barh <class 'function'>
cbook <class 'module'>
cla <class 'function'>
clabel <class 'function'>
clf <class 'function'>
clim <class 'function'>
close <class 'function'>
cm <class 'module'>
cohere <class 'function'>
colorbar <class 'function'>
colormaps <class 'function'>
connect <class 'function'>
contour <class 'function'>
contourf <class 'function'>
cool <class 'function'>
copper <class 'function'>
csd <class 'function'>
cycler <class 'function'>
dedent <class 'function'>
delaxes <class 'function'>
deprecated <class 'function'>
disconnect <class 'function'>
docstring <class 'module'>
draw <class 'function'>
draw_all <class 'method'>
draw_if_interactive <class 'function'>
errorbar <class 'function'>
eventplot <class 'function'>
figaspect <class 'function'>
figimage <class 'function'>
figlegend <class 'function'>
fignum_exists <class 'function'>
figtext <class 'function'>
figure <class 'function'>
fill <class 'function'>
fill_between <class 'function'>
fill_betweenx <class 'function'>
findobj <class 'function'>
flag <class 'function'>
functools <class 'module'>
gca <class 'function'>
gcf <class 'function'>
gci <class 'function'>
get <class 'function'>
get_backend <class 'function'>
get_cmap <class 'function'>
get_current_fig_manager <class 'function'>
get_figlabels <class 'function'>
get_fignums <class 'function'>
get_plot_commands <class 'function'>
get_scale_docs <class 'function'>
get_scale_names <class 'function'>
getp <class 'function'>
ginput <class 'function'>
gray <class 'function'>
grid <class 'function'>
hexbin <class 'function'>
hist <class 'function'>
hist2d <class 'function'>
hlines <class 'function'>
hot <class 'function'>
hsv <class 'function'>
importlib <class 'module'>
imread <class 'function'>
imsave <class 'function'>
imshow <class 'function'>
inferno <class 'function'>
inspect <class 'module'>
install_repl_displayhook <class 'function'>
interactive <class 'function'>
ioff <class 'function'>
ion <class 'function'>
isinteractive <class 'function'>
jet <class 'function'>
legend <class 'function'>
locator_params <class 'function'>
logging <class 'module'>
loglog <class 'function'>
magma <class 'function'>
magnitude_spectrum <class 'function'>
margins <class 'function'>
matplotlib <class 'module'>
matshow <class 'function'>
minorticks_off <class 'function'>
minorticks_on <class 'function'>
mlab <class 'module'>
new_figure_manager <class 'method'>
nipy_spectral <class 'function'>
np <class 'module'>
pause <class 'function'>
pcolor <class 'function'>
pcolormesh <class 'function'>
phase_spectrum <class 'function'>
pie <class 'function'>
pink <class 'function'>
plasma <class 'function'>
plot <class 'function'>
plot_date <class 'function'>
plotfile <class 'function'>
plotting <class 'function'>
polar <class 'function'>
prism <class 'function'>
psd <class 'function'>
pylab_setup <class 'function'>
quiver <class 'function'>
quiverkey <class 'function'>
rc <class 'function'>
rcParams <class 'matplotlib.RcParams'>
rcParamsDefault <class 'matplotlib.RcParams'>
rcParamsOrig <class 'matplotlib.RcParams'>
rc_context <class 'function'>
rcdefaults <class 'function'>
rcsetup <class 'module'>
re <class 'module'>
register_cmap <class 'function'>
rgrids <class 'function'>
savefig <class 'function'>
sca <class 'function'>
scatter <class 'function'>
sci <class 'function'>
semilogx <class 'function'>
semilogy <class 'function'>
set_cmap <class 'function'>
set_loglevel <class 'function'>
setp <class 'function'>
show <class 'function'>
silent_list <class 'type'>
specgram <class 'function'>
spring <class 'function'>
spy <class 'function'>
stackplot <class 'function'>
stem <class 'function'>
step <class 'function'>
streamplot <class 'function'>
style <class 'module'>
subplot <class 'function'>
subplot2grid <class 'function'>
subplot_tool <class 'function'>
subplots <class 'function'>
subplots_adjust <class 'function'>
summer <class 'function'>
suptitle <class 'function'>
switch_backend <class 'function'>
sys <class 'module'>
table <class 'function'>
text <class 'function'>
thetagrids <class 'function'>
tick_params <class 'function'>
ticklabel_format <class 'function'>
tight_layout <class 'function'>
time <class 'module'>
title <class 'function'>
tricontour <class 'function'>
tricontourf <class 'function'>
tripcolor <class 'function'>
triplot <class 'function'>
twinx <class 'function'>
twiny <class 'function'>
uninstall_repl_displayhook <class 'function'>
violinplot <class 'function'>
viridis <class 'function'>
vlines <class 'function'>
waitforbuttonpress <class 'function'>
warn_deprecated <class 'function'>
winter <class 'function'>
xcorr <class 'function'>
xkcd <class 'function'>
xlabel <class 'function'>
xlim <class 'function'>
xscale <class 'function'>
xticks <class 'function'>
ylabel <class 'function'>
ylim <class 'function'>
yscale <class 'function'>
yticks <class 'function'>
…
tags: advanced & category: python