I keep getting
<__main__.Camera object at 0x02C08790>
and I don't know why.
I would like the code to go from Calc_Speed to Counter and then back to Calc_Speed basically in a loop.
class Camera():
distance = 2
speed_limit = 20
number_of_cars = 0
def Calc_Speed(self):
registration = input("Registration Plate: ")
Speeding_List=[]
start = float(input("Start time: "))
end = float(input("End Time: "))
speed = self.distance/(end-start)
print(("Average Speed: ") + str(round(speed, 2)) + (" mph"))
if speed > self.speed_limit:
list3= [str(self.registration)]
Speeding_List.append(list3)
print("Vehicles Caught Speeding: " + str(Speeding_List))
return(program.Counter())
else:
print("Vehicle Not Speeding")
return(program.Counter())
def Counter():
self.number_of_cars = self.number_of_cars + 1
print("Number Of Cars Recorded: " + str(self.number_of_cars))
return(program.Calc_Speed())
program = Camera()
print(program)
When you just print an object, it shows the object id (like <__main__.Camera object at 0x02C08790>), which is totally indecipherable to us mortals. You can get around this by defining a __str__ or __repr__ function to display the data for the instance in a custom way.
In your case:
def __repr__(self):
return "<__main__.Camera: distance = " + str(self.distance) + "; speed_limit = " + str(self.speed_limit) + "; number_of_cars = " + str(self.number_of_cars) + ">"
If there were an instance of Camera with the starting variable values, it would return
"<__main__.Camera: distance = 2; speed_limit = 20; number_of_cars = 0>".
The <__main__.Camera object at 0x02C08790> is the how the system remembers it, but aside from showing what type of object it is, it's mostly useless.
Rather than printing the object itself, you would want to print a function of that object. If you replaced the last line with:
print(program.Calc_Speed())
The program would work more similarly to what you seem to be looking for.
I wrote this answer for a linked closed duplicate. Since it goes into more detail about why the output looks like this, and this is apparently the canonical question, I'm putting it here.
Because you are printing an object, and that object doesn't have a __repr__ or __str__ method explaining how to print it.
Implementing these methods will let you print a 'description' of your object.
Background
When you call print(thing) in python, print looks to see if thing has a __str__ method, and calls it if it does. If it doesn't, it looks to see whether thing has a __repr__ method, and calls that if it does. If not, it keeps looking up the class hierarchy,* until it ends up with object, from which all user defined classes inherit (nowadays...). That's the method you're seeing here.
We can try this out:
>>> "I am a string".__str__()
"I am a string"
>>> "I am a string".__repr__()
"'I am a string'"
Yes! strings are objects in python. In fact, everything is an object.
>>> obj = object() # base class for all classes
obj.__str__()
'<object object at 0x7a87787987979877>'
So it's the fallback .__str__, which just prints that it's a thing at such and such a ram address.
*alright, it'll apply MRO, but I was keeping it simple.
I found with Dash:
print(InputData.marker_value)
>>> <dash._callback.NoUpdate object at 0x7f52b29fdfa0>
print(InputData().marker_value)
>>> "value expected"
I agree with Sandford Basset
You can try as well
program.Calc_Speed()
Related
I am attempting to take the source code of a function, add code to it, and then put it back in the original function.
Basically like so:
new_code = change_code(original_code)
throwaway_module = ModuleType('m')
exec(new_code, throwaway_module.__dict__)
func.__code__ = getattr(throwaway_module, func.__name__).__code__
This works perfectly when new_code doesn't contain any name which wasn't in the original function.
However when new_code contains a variable name which wasn't there in the original func, then on the last line I get the following error:
ValueError: func() requires a code object with 1 free vars, not 0
Any ideas?
EDIT:
It seems I have found where in the CPython source code this exception is raised (file funcobject.c). Omitted some lines for clarity:
static int
func_set_code(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored))
{
Py_ssize_t nfree, nclosure;
// ... lines omitted
nfree = PyCode_GetNumFree((PyCodeObject *)value);
nclosure = (op->func_closure == NULL ? 0 :
PyTuple_GET_SIZE(op->func_closure));
if (nclosure != nfree) {
PyErr_Format(PyExc_ValueError,
"%U() requires a code object with %zd free vars,"
" not %zd",
op->func_name,
nclosure, nfree);
return -1;
}
Py_INCREF(value);
Py_XSETREF(op->func_code, value);
return 0;
}
Does this help you help me? :)
This exception is due to attempting to assign a code object to a function which closes over a different number of variables than the function it came from did. If that sentence sounded like gibberish then you should take a look at this answer.
The easiest way to avoid this problem is to simply reassign the existing name in the obvious way, ie f = g instead of f.__code__ = g.__code__. By doing it this way the code object always stays with its matching closure (more on that later). In your case, that would look like func = getattr(throwaway_module, func.__name__). Is there some reason you can't do this and were mucking around with internal implementation details instead?
In order to better illustrate what's happening here, suppose we have some silly functions.
def dog():
return "woof"
def cat():
return "meow"
def do_stuff(seq):
t1 = sum(seq)
seq2 = [e + t1 for e in seq]
t2 = sum(seq2)
return t1 + t2
def pair(animal):
def ret():
return animal() + animal()
return ret
cats = pair(cat)
print(dog()) # woof
print(cat()) # meow
print(cats()) # meowmeow
print(do_stuff([1,2,3])) # 30
Even though do_stuff has a different number of local variables than dog, we can still successfully reassign code objects between them.
do_stuff.__code__ = dog.__code__
print(do_stuff()) # woof
However, we can't reassign between cats and dog because cats closes over the argument animal.
print(cats.__code__.co_freevars) # ('animal',)
dog.__code__ = cats.__code__
ValueError: dog() requires a code object with 0 free vars, not 1
This problem can be avoided by simply reassigning the name to the desired function object.
dog = cats
print(dog()) # meowmeow
In fact, if you were to successfully pull off a code object reassignment for a function with a closure, things would most likely not go as expected if the function were executed. This is because the closed over variables are saved separately from the compiled code, so they wouldn't match.
def get_sum_func(numbers):
def ret():
return sum(numbers)
return ret
sum_func = get_sum_func([2,2,2]) # sum_func closes over the provided arg
# swap code objects
# quite possibly the most disturbing single line of python I've ever written
sum_func.__code__, cats.__code__ = (cats.__code__, sum_func.__code__)
print(sum_func()) # this will attempt to execute numbers() + numbers(), which will throw
print(cats()) # this will attempt to execute sum(animal), which will throw
As it turns out, we can't easily replace the __closure__ attribute because it is read-only. You could presumably work around it if you were really determined, but that's almost certainly a terrible idea.
# swap closures
# this results in "AttributeError: readonly attribute"
sum_func.__closure__, cats.__closure__ = (cats.__closure__, sum_func.__closure__)
For more details about function object attributes, see this answer and the docs.
Hello i have a weird doubt..
MY code is
def prints():
print " I WILL DIE HEHE"
def add(a,b):
next = a
print " Added sum is %d " % (next + b)
next = prints()
w = int(raw_input("Give a"))
g = int(raw_input("Give b"))
add(w,g)
Now the problem is why does the function prints() gets executed while i assign it to next i.e. next = prints(). I am little confused.
Because you are calling it,
prints()
will execute where as
ne = prints
ne()
is assigning the name, and then calling the new name.
Noteback, I also call it ne as next shadows a builtin method
The following:
next = prints()
calls prints(), and assigns the result to next. Since prints() doesn't explicitly return anything, it implicitly returns None, and thus next is set to None.
It is not entirely clear what you're expecting or trying to achieve, but it may be helpful to consider the following:
next = prints
What this does is assign the function object to next. It does not call the function, but allows it to be called as next().
I made a simple code to demonstrate and understand classes - however when I run this, my lists show that they are empty, containing "None" values instead of the strings that the user enters as names.
#Static methods do not require the object to be initiated. Can be remotely accessed from outside the function .
#Counting critters and remote access.
class Orc (object):
total = 0
def get_score (self):
print "The number of orcs the orc factory has made is",Orc.total
def __init__ (self):
Orc.total += 1
name = raw_input ("I am a critter by the name of:\n")
#Creating 10 Orcs
list = []
for i in range (4): list[i] = list.append(Orc.get_score(Orc()))
print "You have created 4 Orcs!" print "The name of your first orc is",list[0] print "The name of your fourth orc is", list[3]
There are a few errors in your code. First in the way you use lists. Second, in the way you call methods on your objects. The combination of errors explains why you have a list of None at the end.
List name
list = []
Don't name a list list. It is already the name of, well..., the list class, i.e. in Python you can do my_list = [] or my_list = list() with the exact same effect.
You want to call your list something meaningful, like orc_list
List Insertion
for i in range (4):
orc_list[i] = orc_list.append(...)
orc_list.append does what it says: it appends an element to the given list. However, it does not return anything. So what your code is doing is
taking an empty list
setting i to 0
inserting what you pass to append at the end of the list
inserting None at index i and thus overriding what you did in 3.
incrementing i
going back to 3.
You want to simply use orc_list.append(...)
Method Call
Orc.get_score(Orc())
I imagine you are getting confused by the self argument. In a class, Python will automatically pass the instance you are working on as the self argument. You don't need to provide that argument.
You want to write
Orc().get_score()
This creates an Orc object, and then calls get_score on it. Python 'injects' the Orc instance you have created into get_score for you.
Method Return
We're now down to
orc_list.append(Orc().get_score())
which is equivalent to
score = Orc().get_score()
orc_list.append(score)
The problem is that there is no return statement in get_score. This means that python will return None when you call that method. Which means that you are appending None to your list.
You want to have
def get_score(self):
print "The number of orcs the orc factory has made is", Orc.total
return Orc.total
Static behaviour
If you really wanted to have a method not bound to an instance of the Orc class, you could use either a class method or a static method.
In your case, you do not need to do anything to the class object, so your choice would be to use a static method.
You would declare
#staticmethod
def get_score():
print "The number of orcs the orc factory has made is", Orc.total
You would then call that method using Orc.get_score()
To define a class method in Python, use classethod decorator and call the first parameter cls
class Orc(object):
total = 0
#classmethod # this will make the method a class method
def get_score (cls): # convention is then to call the 1st param 'cls'
print "The number of orcs the orc factory has made is", cls.total
def __init__ (self):
Orc.total += 1
# use self is you want' to register a name
# however putting a raw_input in an __init__ is NOT recommanded
# you should pass name as a parameter
# and call the raw_input in the for loop
self.name = raw_input ("I am a critter by the name of:\n")
orcs = [] # don't call your lists 'list' because `list` is standard Python function
for i in range(4): # put this on two lines for clarity or use a comprehension list
orcs.append(Orc())
print "You have created 4 Orcs!"
print "The name of your first orc is", orcs[0].name # if you don't use `name`, you will see the reference of the object
print "The name of your fourth orc is", orcs[3].name
A cleaner version (something you should aim for):
class Orc(object):
total = 0
#classmethod #
def get_instances_count(cls):
"""
Return the number or orcs that have been instanciated
"""
# ^ Put some documentation below your method
# these are called "docstring" and are detected by Python
# you should return values in method rather than print
# there are rare cases when you do want print, but when you'll
# encounter them, you won't need me to correct your code anymore
return cls.total
def __init__ (self, name):
Orc.total += 1
self.name = name # we get the name as a parameter
l = []
for i in range(4): # put this on two lines for clarity or use a comprehension list
orc = Orc(raw_input("Enter a name:\n"))
l.append(orc)
print "You have created %s Orcs!" % Orc.get_instances_count()
print "The name of your first orc is", l[0].name #
print "The name of your fourth orc is", l[3].name
Now the more Pythonic version (something you should be able to do once used to Python):
class Orc(object):
total = 0
# you don't need accessors in Python: most things are public anyway
# and you got property
def __init__ (self, name):
Orc.total += 1
self.name = name # we get the name as a parameter
def __str__(self):
# this will be call when printing an orc
return self.name
# list comprehension are quick and clean ways to create lists
# give a real name to your list
orcs = [Orc(raw_input("Enter a name:\n")) for i in range(4)]
# using parenthesis for `print` is a good habit to take with then incoming Python 3
print("You have created %s Orcs!" % Orc.total)
for i, orc in enumerate(orcs):
print("Orc #%s is %s" % (i, orc))
list.append returns a None value, so it essentially never makes sense to assign its result to anything. You call append for the side-effects, i.e., to have it put a value at the end of the list. Like this:
for i in range (4):
list.append(Orc.get_score(Orc()))
I don't think the Orc.get_score(Orc()) is what you want, either: it also returns None instead of a score and the method call is technically correct but unlikely to be what you really intend.
Why should there be something in your list?
you do:
list.append(Orc.get_score(Orc())
which is equivalent to:
item_to_add = Orc.get_score(Orc())
list.append(item_to_add)
Your method Orc.get_score has no return statement, so it returns None. therefore, item_to_add will be None, and None will be appended to your list.
As a side note: python is not java. Dont use classes just to use classes. Use classes, when you want to follow OO-Pradigma, i.e. sending messages to objects.
So as part of problem 17.6 in "Think Like a Computer Scientist", I've written a class called Kangaroo:
class Kangaroo(object):
def __init__(self, pouch_contents = []):
self.pouch_contents = pouch_contents
def __str__(self):
'''
>>> kanga = Kangaroo()
>>> kanga.put_in_pouch('olfactory')
>>> kanga.put_in_pouch(7)
>>> kanga.put_in_pouch(8)
>>> kanga.put_in_pouch(9)
>>> print kanga
"In kanga's pouch there is: ['olfactory', 7, 8, 9]"
'''
return "In %s's pouch there is: %s" % (object.__str__(self), self.pouch_contents)
def put_in_pouch(self, other):
'''
>>> kanga = Kangaroo()
>>> kanga.put_in_pouch('olfactory')
>>> kanga.put_in_pouch(7)
>>> kanga.put_in_pouch(8)
>>> kanga.put_in_pouch(9)
>>> kanga.pouch_contents
['olfactory', 7, 8, 9]
'''
self.pouch_contents.append(other)
What's driving me nuts is that I'd like to be able to write a string method that would pass the unit test underneath __str__ as written. What I'm getting now instead is:
In <__main__.Kangaroo object at 0x4dd870>'s pouch there is: ['olfactory', 7, 8, 9]
Bascially, what I'm wondering if there is some function that I can perform on kanga = Kangaroo such that the output of the function is those 5 characters, i.e. function(kanga) -> "kanga".
Any ideas?
Edit:
Reading the first answer has made me realize that there is a more concise way to ask my original question. Is there a way to rewrite __init__ such that the following code is valid as written?
>>> somename = Kangaroo()
>>> somename.name
'somename'
To put your request into perspective, please explain what name you would like attached to the object created by this code:
marsupials = []
marsupials.append(Kangaroo())
This classic essay by the effbot gives an excellent explanation.
To answer the revised question in your edit: No.
Now that you've come clean in a comment and said that the whole purpose of this naming exercise was to distinguish between objects for debugging purposes associated with your mutable default argument:
In CPython implementations of Python at least, at any given time, all existing objects have a unique ID, which may be obtained by id(obj). This may be sufficient for your debugging purposes. Note that if an object is deleted, that ID (which is a memory address) can be re-used by a subsequently created object.
I wasn't going to post this but if you only want this for debugging then here you go:
import sys
class Kangaroo(object):
def __str__(self):
flocals = sys._getframe(1).f_locals
for ident in flocals:
if flocals[ident] is self:
name = ident
break
else:
name = 'roo'
return "in {0}'s pouch, there is {1}".format(name, self.pouch_contents)
kang = Kangaroo()
print kang
This is dependent on CPython (AFAIK) and isn't suitable for production code. It wont work if the instance is in any sort of container and may fail for any reason at any time. It should do the trick for you though.
It works by getting the f_locals dictionary out of the stack frame that represents the namespace where print kang is called. The keys of f_locals are the names of the variables in the frame so we just loop through it and test if each entry is self. If so, we break. If break is not executed, then we didn't find an entry and the loops else clause assigns the value 'roo' as requested.
If you want to get it out of a container of some sort, you need to extend this to look through any containers in f_locals. You could either return the key if it's a dictlike container or the index if it's something like a tuple or list.
class Kangaroo(object):
def __init__(self, pouch_contents=None, name='roo'):
if pouch_contents is None:
self.pouch_contents = [] # this isn't shared with all other instances
else:
self.pouch_contents = pouch_contents
self.name = name
...
kanga = Kangaroo(name='kanga')
Note that it's good style not to put spaces around = in the arguments
What you want is basically impossible in Python, even with the suggested "hacks". For example,
what would the following code print?
>>> kanga1 = kanga2 = kanga3 = Kangaroo()
>>> kanga2.name
???
>>> kanga3.name
???
or
>>> l = [Kangaroo()]
>>> l[0].name
???
If you want "named" objects, just supply a name to your object
def __init__(self, name):
self.name = name
More explicit (which we like with Python) and consistent in all cases. Sure you can do something like
>>> foo = Kangaroo("bar")
>>> foo.name
'bar'
but foo will be just one of the possibly many labels the instance has. The name is explicit and permanent. You can even enforce unique naming if you want (while you can reuse a variable as much as you want for different objects)
I hadn't seen aaronasterling's hackish answer when I started working on this, but in any case here's a hackish answer of my own:
class Kangaroo(object):
def __init__(self, pouch_contents = ()):
self.pouch_contents = list(pouch_contents)
def __str__(self):
if not hasattr(self, 'name'):
for k, v in globals().iteritems():
if id(v) == id(self):
self.name = k
break
else:
self.name = 'roo'
return "In %s's pouch there is: %s" % (self.name, self.pouch_contents)
kanga = Kangaroo()
print kanga
You can break this by looking at it funny (it works as written, but it will fail as part of a doctest), but it works. I'm more concerned with what's possible than with what's practical at this point in my learning experience, so I'm glad to see that there are at least two different ways to do a thing I figured should be possible to do. Even if they're bad ways.
I'd like to do something like below: particularly the 'f.eval(field)' part, such that it evaluates the value of the variable as the field name. How does one accomplish this in Python?
def punctuated_object_list(objects, field):
field_list = [f.eval(field) for f in objects]
if len(field_list) > 0:
if len(field_list) == 1:
return field_list[0]
else:
return ', '.join(field_list[:-1]) + ' & ' + field_list[-1]
else:
return u''
getattr(f, field), if I understand you correctly (that is, if you might have field = "foo", and want f.foo). If not, you might want to clarify. Python has an eval(), and I don't know what other languages' eval() you want the equivalent of.
getattr( object, 'field' ) #note that field is a string
f = 'field_name'
#...
getattr( object, f )
#to get a list of fields in an object, you can use dir()
dir( object )
For more details, see: http://www.diveintopython.org/power_of_introspection/index.html
Don't use eval, even if the strings are safe in this particular case! Just don't get yourself used to it. If you're getting the string from the user it could be malicious code.
Murphy's law: if things can go wrong, they will.
The python equivalent of eval() is eval()
x = 9
eval("x*2")
will give you 18.
v = "x"
eval(v+"*2")
works too.
To get at a list of all the fields in a Python object you can access its __dict__ property.
class Testing():
def __init__(self):
self.name = "Joe"
self.age = 30
test = Testing()
print test.__dict__
results:
{'age': 30, 'name': 'Joe'}