how to create an instance of class python - python

I am learning about classes in Python, using Python 3.4.1 and am attempting to make a class and then call the methods from that class. I have looked at other questions related to this and unfortunately, I can't seem to make it work. Here is my class (copied straight from the book)
class Counter(object):
"""Models a counter"""
instances = 0
def __init__(self):
"""Sets up counter"""
Counter.instances += 1
self.reset()
def reset(self):
"""Sets counter to 0"""
self._value=0
def increment(self, amount = 1):
"""Adds amount to counter"""
self._value += amount
def decrement(self, amount = 1):
"""Subtracts amount from counter"""
self._value -= amount
def getValue(self):
return self._value
def __str__(self):
return str(self._value)
def __eq__(self, other):
"""Returns True if self == other and False if not"""
if self is other:
return True
if type(self)!=type(other):
return False
return self._value==other._value
and this is how I'm calling it from another file (in the same folder):
import Counter
h = Counter()
print(h.getValue())
and this is the error I'm getting:
Traceback (most recent call last):
File "C:/Python34/learning/classtest.py", line 3, in <module>
h = Counter()
TypeError: 'module' object is not callable
I can type import Counter just fine into the shell, but when I get to h = Counter() I get the same error. I know I'm doing something wrong, but what?

You named your module Counter too; the class is contained in the module:
import Counter
h = Counter.Counter()
Alternatively, import the class from the module:
from Counter import Counter
h = Counter()
This is why the Python style guide recommends you use all lower-case names for your modules. In Python, the module name does not have to match the class contained, and you are not limited to just one class in a module. A module can contain just functions or any other Python object too.
Had you named your module file counter (all lowercase) instead, it would perhaps have been more obvious that the module and contained class are two distinct concepts. :-)

In simple terms, the line:
import Counter
only makes the module Counter available for use. If you want to use one of the tools that it contains, such as the class Counter, you need to qualify it with the module name:
import Counter
h = Counter.Counter()
Or, you can import the tools you want directly:
from Counter import Counter
h = Counter()
Here is a reference on importing in Python.
Also, PEP 8, the official style guide for Python code, states that module names should be lowercase:
Modules should have short, all-lowercase names. Underscores can be
used in the module name if it improves readability. Python packages
should also have short, all-lowercase names, although the use of
underscores is discouraged.
Therefore, it would be best if you renamed the Counter module to counter.

You want Counter.Counter instead, because your file is named Counter.py as well.
If you don't call h = Counter.Counter(), you are basically trying to invoke the module as a function:
>>> import math
>>> math()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'module' object is not callable
You have two options.
1. Call import Counter and then call h = Counter.Counter()
import Counter
h = Counter.Counter()
print(h.getValue())
2. Call from Counter import Counter and then call h = Counter()
from Counter import Counter
h = Counter()
print(h.getValue())

Related

Uses of the copy module (over just making a new variable) in Python?

Say I had code like this:
class Animals:
def __init__(self):
print('Woah')
def Eat(self):
print('yum')
And then you made an animals Gilberto:
gilberto = Animals()
And then you wanted to make another animal named Elijah. Why would you use the copy module:
elijah = copy.copy(gilberto)
When you could just do:
elijah = gilberto
Is there anything special about the copy module? In the case of the Animals class, it seems the same.
When using copy.copy you're creating a new object, instead of referencing the same object (which is what you're doing in the last snippet).
Consider this:
Setting up
import copy
class Animals:
def __init__(self):
print('Woah')
def Eat(self):
print('yum')
gilberto = Animals()
elijah_copy = copy.copy(gilberto)
elijah_reference = gilberto
In the interpreter
>>> id(gilberto) == id(elijah_copy) # Different objects!
False
>>> id(gilberto) == id(elijah_reference) # It's the same object!
True
So if I were to, for example, define a new attribute in elijah_reference it would be available in gilberto also, but not in elijah_copy:
elijah_reference.color = 'red'
In the interpreter
>>> gilberto.color
'red'
>>> elijah_copy.color
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Animals' object has no attribute 'color'

TypeError: 'dict' object is not callable from main

I wrote a code which is going to store occurrences of words from a text file and store it to a dictionary:
class callDict(object):
def __init__(self):
self.invertedIndex = {}
then I write a method
def invertedIndex(self):
print self.invertedIndex.items()
and here is how I am calling:
if __name__ == "__main__":
c = callDict()
c.invertedIndex()
But it gives me the error:
Traceback (most recent call last):
File "E\Project\xyz.py", line 56, in <module>
c.invertedIndex()
TypeError: 'dict' object is not callable
How can I resolve this?
You are defining a method and an instance variable in your code, both with the same name. This will result in a name clash and hence the error.
Change the name of one or the other to resolve this.
So for example, this code should work for you:
class CallDict(object):
def __init__(self):
self.inverted_index = {}
def get_inverted_index_items(self):
print self.inverted_index.items()
And check it using:
>>> c = CallDict()
>>> c.get_inverted_index_items()
[]
Also check out ozgur's answer for doing this using #property decorator.
In addition to mu's answer,
#property
def invertedIndexItems(self):
print self.invertedIndex.items()
then here is how you'll cal it:
if __name__ == "__main__":
c = callDict()
print c.invertedIndexItems
Methods are attributes in Python, so you can't share the same name between them. Rename one of them.

Constructor that takes in a method

In Python, can a constructor take in a method of another class as an argument?
I've heard that you can do something like this, but this example isn't working (currently, I'm getting a 'module' object is not callable error):
class GeneticAlgorithm ():
def __init__(self, population, fitness, breed, retain = .3, weak_retain = .15 ) :
self.fitness = fitness
Here fitness is a function defined elsewhere and note that I am importing the class where the function is defined.
edit: Here's the code that actually produces the error
class Solver( ):
def __init__( self, fitness, breed, iterations ):
self.T = Problem()
self.fitness = fitness
self.breed = breed
self.iterations = iterations
def solve( self ):
P = self.T.population(500)
GA = GeneticAlgorithm(P, self.fitness, self.breed) # problem here
Traceback (most recent call last):
File "C:\Users\danisg\Desktop\Other\Problem.py", line 128, in <module>
main()
File "C:\Users\danisg\Desktop\Other\Problem.py", line 124, in main
t = S.solve()
File "C:\Users\danisg\Desktop\Other\Problem.py", line 74, in solve
GA = GeneticAlgorithm(P, self.fitness, self.breed)
TypeError: 'module' object is not callable
And where the Solver is created
def main():
S = Solver(fitness, breed, 35)
print(S.solve())
if __name__ == '__main__':
main()
From the comments, the root of the issue:
I do `import GeneticAlgorithm'. I should not do this? – gjdanis
No, that's not actually correct. What you've done is import the module, not the class that's inside the module. You have two options here - do one or the other:
Change the import to
from GeneticAlgorithm import GeneticAlgorithm
Change the Solver class to use
GA = GeneticAlgorithm.GeneticAlgorithm(P, self.fitness, self.breed)
I'd suggest renaming the module from GeneticAlgorithm.py to something that isn't quite as confusing (genetic_algorithm.py is a good candidate), then using the first option to import just the class from that module - from genetic_algorithm import GeneticAlgorithm
Yes, you could have something like this:
def eats_a_method(the_method):
pass
def another_method():
pass
eats_a_method(another_method)
Take a look at the stack trace:
GA = GeneticAlgorithm(P, self.fitness, self.breed)
TypeError: 'module' object is not callable
It says GeneticAlgorithm is a module, not a function.

Function into a Python class

I am new in Python and I wrote the following code:
class Frazione:
def __init__(self, Numeratore, Denominatore=1):
mcd=MCD(Numeratore,Denominatore)
self.Numeratore=Numeratore/mcd
self.Denominatore=Denominatore/mcd
def MCD(m,n):
if m%n==0:
return n
else:
return MCD(n,m%n)
def __str__(self):
return "%d/%d" %(self.Numeratore, self.Denominatore)
def __mul__(self, AltraFrazione):
if type(AltraFrazione)==type(5):
AltraFrazione=Frazione(AltraFrazione)
return Frazione(self.Numeratore*AltraFrazione.Numeratore, self.Denominatore*AltraFrazione.Denominatore)
__rmul__=__mul__
Open shell at the same folder of Frazione.py:
>>> from Frazione import Frazione
end then
>>> f=Frazione(10,5)
When I press Enter, I receive this output:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".\Frazione.py", line 5, in __init__
mcd=MCD(Numeratore,Denominatore)
NameError: global name 'MCD' is not defined
PS. I apologize for my english!
MCD is a method of Frazione, but you're calling it as if it were a global function. The easiest (and cleanest, IMHO) fix is to just move it outside the class, because it doesn't need to access any class or instance members.
So:
def MCD(m, n):
if m % n == 0:
return n
else:
return MCD(n, m % n)
class Frazione:
# as before but without MCD
If you do want to keep it in the class, then you might rewrite it to be iterative instead of recursive and call it as self.MCD in __init__. That's a good idea anyway, as Python's support for recursion is rather weak.

How to watch for a variable change in python without dunder setattr or pdb

There is large python project where one attribute of one class just have wrong value in some place.
It should be sqlalchemy.orm.attributes.InstrumentedAttribute, but when I run tests it is constant value, let's say string.
There is some way to run python program in debug mode, and run some check (if variable changed type) after each step throught line of code automatically?
P.S. I know how to log changes of attribute of class instance with help of inspect and property decorator. Possibly here I can use this method with metaclasses...
But sometimes I need more general and powerfull solution...
Thank you.
P.P.S. I need something like there: https://stackoverflow.com/a/7669165/816449, but may be with more explanation of what is going on in that code.
Well, here is a sort of slow approach. It can be modified for watching for local variable change (just by name). Here is how it works: we do sys.settrace and analyse the value of obj.attr each step. The tricky part is that we receive 'line' events (that some line was executed) before line is executed. So, when we notice that obj.attr has changed, we are already on the next line and we can't get the previous line frame (because frames aren't copied for each line, they are modified ). So on each line event I save traceback.format_stack to watcher.prev_st and if on the next call of trace_command value has changed, we print the saved stack trace to file. Saving traceback on each line is quite an expensive operation, so you'd have to set include keyword to a list of your projects directories (or just the root of your project) in order not to watch how other libraries are doing their stuff and waste cpu.
watcher.py
import traceback
class Watcher(object):
def __init__(self, obj=None, attr=None, log_file='log.txt', include=[], enabled=False):
"""
Debugger that watches for changes in object attributes
obj - object to be watched
attr - string, name of attribute
log_file - string, where to write output
include - list of strings, debug files only in these directories.
Set it to path of your project otherwise it will take long time
to run on big libraries import and usage.
"""
self.log_file=log_file
with open(self.log_file, 'wb'): pass
self.prev_st = None
self.include = [incl.replace('\\','/') for incl in include]
if obj:
self.value = getattr(obj, attr)
self.obj = obj
self.attr = attr
self.enabled = enabled # Important, must be last line on __init__.
def __call__(self, *args, **kwargs):
kwargs['enabled'] = True
self.__init__(*args, **kwargs)
def check_condition(self):
tmp = getattr(self.obj, self.attr)
result = tmp != self.value
self.value = tmp
return result
def trace_command(self, frame, event, arg):
if event!='line' or not self.enabled:
return self.trace_command
if self.check_condition():
if self.prev_st:
with open(self.log_file, 'ab') as f:
print >>f, "Value of",self.obj,".",self.attr,"changed!"
print >>f,"###### Line:"
print >>f,''.join(self.prev_st)
if self.include:
fname = frame.f_code.co_filename.replace('\\','/')
to_include = False
for incl in self.include:
if fname.startswith(incl):
to_include = True
break
if not to_include:
return self.trace_command
self.prev_st = traceback.format_stack(frame)
return self.trace_command
import sys
watcher = Watcher()
sys.settrace(watcher.trace_command)
testwatcher.py
from watcher import watcher
import numpy as np
import urllib2
class X(object):
def __init__(self, foo):
self.foo = foo
class Y(object):
def __init__(self, x):
self.xoo = x
def boom(self):
self.xoo.foo = "xoo foo!"
def main():
x = X(50)
watcher(x, 'foo', log_file='log.txt', include =['C:/Users/j/PycharmProjects/hello'])
x.foo = 500
x.goo = 300
y = Y(x)
y.boom()
arr = np.arange(0,100,0.1)
arr = arr**2
for i in xrange(3):
print 'a'
x.foo = i
for i in xrange(1):
i = i+1
main()
There's a very simple way to do this: use watchpoints.
Basically you only need to do
from watchpoints import watch
watch(your_object.attr)
That's it. Whenever the attribute is changed, it will print out the line that changed it and how it's changed. Super easy to use.
It also has more advanced features, for example, you can call pdb when the variable is changed, or use your own callback functions instead of print it to stdout.
A simpler way to watch for an object's attribute change (which can also be a module-level variable or anything accessible with getattr) would be to leverage hunter library, a flexible code tracing toolkit. To detect state changes we need a predicate which can look like the following:
import traceback
class MutationWatcher:
def __init__(self, target, attrs):
self.target = target
self.state = {k: getattr(target, k) for k in attrs}
def __call__(self, event):
result = False
for k, v in self.state.items():
current_value = getattr(self.target, k)
if v != current_value:
result = True
self.state[k] = current_value
print('Value of attribute {} has chaned from {!r} to {!r}'.format(
k, v, current_value))
if result:
traceback.print_stack(event.frame)
return result
Then given a sample code:
class TargetThatChangesWeirdly:
attr_name = 1
def some_nested_function_that_does_the_nasty_mutation(obj):
obj.attr_name = 2
def some_public_api(obj):
some_nested_function_that_does_the_nasty_mutation(obj)
We can instrument it with hunter like:
# or any other entry point that calls the public API of interest
if __name__ == '__main__':
obj = TargetThatChangesWeirdly()
import hunter
watcher = MutationWatcher(obj, ['attr_name'])
hunter.trace(watcher, stdlib=False, action=hunter.CodePrinter)
some_public_api(obj)
Running the module produces:
Value of attribute attr_name has chaned from 1 to 2
File "test.py", line 44, in <module>
some_public_api(obj)
File "test.py", line 10, in some_public_api
some_nested_function_that_does_the_nasty_mutation(obj)
File "test.py", line 6, in some_nested_function_that_does_the_nasty_mutation
obj.attr_name = 2
test.py:6 return obj.attr_name = 2
... return value: None
You can also use other actions that hunter supports. For instance, Debugger which breaks into pdb (debugger on an attribute change).
Try using __setattr__ to override the function that is called when an attribute assignment is attempted. Documentation for __setattr__
You can use the python debugger module (part of the standard library)
To use, just import pdb at the top of your source file:
import pdb
and then set a trace wherever you want to start inspecting the code:
pdb.set_trace()
You can then step through the code with n, and investigate the current state by running python commands.
def __setattr__(self, name, value):
if name=="xxx":
util.output_stack('xxxxx')
super(XXX, self).__setattr__(name, value)
This sample code helped me.

Categories

Resources