Can global variable be used to call function? - python-2.7

SEFC.py:
import time
import traceback
import platform
sefc_verbose = False
obj_sefc = None
class CSEFC():
def __init__(self):
self.fp_platform = False
self.bbu_platform = False
return
def __del__(self):
return
def ipmi_cmd_trace(self):
return False
KCS.py:
import SEFC as sefc
class CKCS(CLogger):
def __init__(self, str_ip = None, int_port = _DEFAULT_ATRAGON_PORT):
CLogger.__init__(self)
self.obj_json_client = None
def send_ipmi_target(self, targetstr, raw_request, int_retry = 3):
if sefc.obj_sefc.ipmi_cmd_trace():
##do stuff
I am reading code written by someone else.I can't seem to understand in if sefc.obj_sefc.ipmi_cmd_trace(): obj_sefc is used to call ipmi_cmd_trace() function. sefc_obj is a global variable I belive. But this code should not work. Also, I doubt my programming ability. This code seems to compile and work for others. Is this correct? Am I missing something here?

With just the code you've shown, you're right, it won't work, since obj_sefc is None in the SEFC module. However, I suspect that some other code that you haven't shown that creates an instance of the CSEFC class and assigns it to that global variable. Then the code you've shown will work.
Its probably not a good design for the code you've shown to be reliant on some other code to be run first, since it will fail if it gets run in the wrong order. However, using a global variable to contain a single instance of a class is not problematic in general. You just want to make sure the code that creates the instance is put somewhere that ensures it will be run before the instance is needed. For instance, the code could be put at the bottom of the SEFC module, or at the top of the KCS module.

Related

What is a def __call__(self,in_data) function used for in python and where is the in_data getting its value

I am actually a student and my teacher gave me this code to understand and use this code so i can continue to learn machine learning etc. I get that it is an AND function and i get what it is printing , the thing i cant understan is the def call(self,in_data): function and where does the "in_data" gets its value from? Because in my point of view all i see it's a blank variable that somehow helps me to complete the code. Also changing the value of the weights in the init part didnt actually change anything in this code and i am wondering why. Here is the whole code i was given to study. Thanks for helping!
import numpy as np
class Perceptron:
def __init__(self,input_length,weights=None):
if weights is None:
self.weights= np.ones(input_length)*0.5
else:
self.weights=weights
#staticmethod
def unit_step_function(x):
if x>0.5:
return 1
return 0
def __call__(self,in_data):
weighted_input=self.weights*in_data
weighted_sum=weighted_input.sum()
return Perceptron.unit_step_function(weighted_sum)
p = Perceptron(2,np.array([0.5,0.5]))
for x in [np.array([0,0]),np.array([0,1]),np.array([1,0]),np.array([1,1])]:
y=p(np.array(x))
print(x,y)
__call__ is called when you try to invoke the object as though it were a function. You can see that being done at the bottom. p is a Perceptron object, but it's being treated as a function when you write
y = p(np.array(x))
So where is the data coming from? It's the np.array(x) that's being passed in.
You can read more about the "dunder"/"magic" methods here.
I'd actually argue that this is an abuse of __call__ though. I wouldn't consider a Perceptron to be inherently function-like. I think using a normal method would be clearer:
class Perceptron:
. . .
def give_input(self, in_data): # Instead of __call__
weighted_input = self.weights*in_data
weighted_sum = weighted_input.sum()
return Perceptron.unit_step_function(weighted_sum)
for x in [np.array([0,0]),np.array([0,1]),np.array([1,0]),np.array([1,1])]:
y = p.give_input(np.array(x)) # Just a typical method call now

Trace method resolution order at runtime

I am working on some code (not mine) and I try to instand it.
There 16 classes in the inheritance tree.
Here area the class according to inspect.getmro(self.__class__)
foo_barcheck.views.barcheck.AdminListActionView
foo_barcheck.views.barcheck.ListActionMixin
djangotools.utils.urlresolverutils.UrlMixin
foo.views.ListActionView
foo.views.ContextMixin
foo.views.fooMixin
djangotools.views.ListActionView
djangotools.views.ListViewMixin
django.views.generic.list.MultipleObjectMixin
django.views.generic.edit.FormMixin
djangotools.views.DTMixin
django.views.generic.base.TemplateView
django.views.generic.base.TemplateResponseMixin
django.views.generic.base.ContextMixin
django.views.generic.base.View
object
I want to trace what happens if I call self.do_magic().
I want to see all do_magic() calls of these 16 classes.
The ideal solution would look like this:
result_of_do_magic, list_of_do_magic_methods = trace_method_calls(self.do_magic)
I have no clue how to implement trace_method_calls(). It should execute the code and trace the method calls at runtime.
Is there a tracing guru which knows how to do this?
AFAIK this needs to be done at runtime, since I don't know if all methods calls the do_magic() of the parents via super().
Update
I don't want to modify the code to be able to trace it. I guess this should be possible, since the mocking library can do comparable magic.
If I understand correctly, I can see 2 solutions here.
1) [Brute-ish and relatively easy] Find all occurrences of "do_magic" in your code and wrap it with decorator like:
def trace_this(fn):
def wrapped(*args, **kwargs):
print("do_magic is called!")
result = fn(*args, **kwargs)
print("Result is:{0}".format(result))
return result
return wrapped
...
#trace_this
def do_magic():
...
2) Run django as:
python -m trace -t manage.py runserver 127.0.0.1:8000 --noreload > trace.txt
and all invoked code would be in trace.txt that you can then parse/analyze with tools you prefer.
According to my understanding what you want are the outer frames of a particular function call to see what classes were called to lead to the method in question.
If it is what you want continue below, else let me know in the comments:
Below is an POC to demonstrate how it works. You can build a decorator out of it.
from __future__ import print_function
import inspect
class A:
def a(self):
stacks = inspect.getouterframes(inspect.currentframe())
for stack in stacks:
frame = stack[0]
klass = frame.f_locals.get("self")
mthd = frame.f_code.co_name
if klass: # to avoid printing modules
print('Called by class: {0}, method: {1}'.format(klass.__class__.__name__, mthd))
class B:
def b(self):
bb = A()
bb.a()
class C:
def c(self):
cc = B()
cc.b()
z = C()
z.c()
Output:
Explanation:
Class C calls Class B which in turn calls Class A
When the execution reaches till A.a() all the classes that inherited A are in the outer frames.
You can extract out just the functionality of A.a() to carve out a decorator so that it will print all outer frames leading upto the function call.

how to group traits together, encapsulating them as a group

I have a coordinate system that it makes sense to treat as a "whole group". They initialize, change, and reset simultaneously. I also like to not re-render as many times as I have coordinates when one changes. Here is the simplified version of what I have in mind, but I can't quite get there. Thanks.
Cleaner code is better in my case even if it uses more advanced features. Could the class 'Coord' be wrapped as a trait itself?
from traits.api import *
class Coord(HasTraits):
x=Float(1.0)
y=Float(1.0)
def __init__(self,**traits):
HasTraits.__init__(self,**traits)
class Model:
coord=Instance(Coord)
#on_trait_change('coord')##I would so have liked this to "just work"
def render(self):#reupdate render whenever coordinates change
class Visualization:
model=Instance(Model)
def increment_x(self):
self.model.coord.x+=1 ##should play well with Model.render
def new_coord(self):
self.model.coord=Coord(x=2,y=2) ##should play well with Model.render
There are a couple of issues with your source code. Model and Visualization both need to be HasTraits classes for the listener to work.
Also, it is rare to actually need to write the __init__ method of a HasTraits class. Traits is designed to work without it. That said, if you do write an __init__ method, make sure to use super to properly traverse the method resolution order. (Note that you will find this inconsistently implemented in the extant documentation and examples.)
Finally, use the 'anytrait' name to listen for any trait:
from traits.api import Float, HasTraits, Instance, on_trait_change
class Coord(HasTraits):
x=Float(1.0)
y=Float(1.0)
class Model(HasTraits):
coord=Instance(Coord, ())
#on_trait_change('coord.anytrait') # listens for any trait on `coord`.
def render(self):
print "I updated"
class Visualization(HasTraits):
model=Instance(Model, ())
def increment_x(self):
self.model.coord.x+=1 # plays well with Model.render
def new_coord(self):
self.model.coord=Coord(x=2,y=2) # plays well with Model.render
Here's my output:
>>> v = Visualization()
>>> v.increment_x()
I updated
>>> v.new_coord()
I updated

IronPython strange method calling

Why does calling a method like this in ironPython work?:
from System.Collections.Generic import List
class test:
mem = None
def __init__(self):
# !No Instance created !!!
self.mem = List[int]
def doSomeThing(self):
if self.mem.Contains((List[int](), 123):
pass
I can't get the behaviour of IronPython in this case: self.mem.Contains((List[int](), 123):. Does any one has an explanation for this?
EDIT
Is self.mem only the type, and Contains will always return False? If this is true, it seems to be a nice feature :)
Thank you!
This is true of normal Python classes as well:
class Foo(object):
def bar(self):
pass
f = Foo
f.bar(Foo())
It's the difference between bound (Foo().bar) and unbound (Foo.bar) methods. It's not so much a feature as a side effect of how methods are implemented in Python.
Contains is always false because it is working on an empty list, which contains nothing.

python 2.7 or 3.2(classes and instances)

I'm a beginner of python. My question is while compiling a project using python, how to make a user-input variable an attribute.
For example:
class supermarket:
num=int(input('enter a no.'))
def __init__(self,num):
self.ini=''
def odd_even(self,num):
if num%2==0:
self.ini='even'
else:
self.ini='odd'
#calling
pallavi=supermarket()
pallavi.(num)
Here, it's showing the error that there is no attribute called num.
What should I do?
This is just a summary and leaves a lot out, but basically, your num should go inside the __init__() call as self.num. So:
class supermarket:
def __init__(self):
self.ini = ''
self.num = int(input('enter a no.'))
# etc.
Then to access the attribute:
pallavi = supermarket()
pallavi.num # No parentheses needed
There's lots more to classes in Python that I don't have time to go into right now, but I'll touch on one thing: until you know what you're doing, all assignments in a class should go inside a function, not in the class definition itself. If you have a statement with a = sign in it that's in the class, not in a function (like the num=int(input("enter a no.")) statement in your example), it's going to fail and you won't understand why.
The reason why goes into the difference between "class variables" and "instance variables", but it might be too soon for you to wrestle with that concept. Still, it might be worth taking a look at the Python tutorial's chapter on classes. If you don't understand parts of that tutorial, don't worry about it yet -- just learn a few concepts, keep on writing code, then go back later and read the tutorial again and a few more concepts may become clear to you.
Good luck!
You have numerous problems here:
num = int(input(...)) assigns a class attribute - this code runs when the class is defined, not when an instance is created, and the attribute will be shared by all instances of the class;
Despite defining a second num parameter to __init__, you call pallavi = supermarket() without passing the argument;
Also, why is num a parameter of odd_even - if it's an attribute, access it via self; and
pallavi.(num) is not correct Python syntax - attribute access syntax is object.attr, the parentheses are a SyntaxError.
I think what you want is something like:
class Supermarket(): # note PEP-8 naming
# no class attributes
def __init__(self, num):
self.num = num # assign instance attribute
self.ini = 'odd' if num % 2 else 'even' # don't need separate method
#classmethod # method of the class, rather than of an instance
def from_input(cls):
while True:
try:
num = int(input('Enter a no.: ')) # try to get an integer
except ValueError:
print("Please enter an integer.") # require valid input
else:
return cls(num) # create class from user input
This separates out the request for user input from the actual initialisation of the instance, and would be called like:
>>> pallavi = Supermarket.from_input()
Enter a no.: foo
Please enter an integer.
Enter a no.: 12
>>> pallavi.num
12
>>> pallavi.ini
'even'
As you mention 3.2 and 2.7, note that input should be replaced with raw_input when using 2.x.