I'm attending a python course in university, where we should implement a deque class as an assignment. Now I've got some problems with the output an instance should give given in the docstring.
class Deque:
"""
>>> d = Deque()
>>> d
Deque<>
>>> d = d.append(1); d
Deque<1>
>>> d.append(2).prepend(0) # allow for chaining of appending & prepending
Deque<0, 1, 2>
I have no idea how to achieve that an instance outputs this notation with the angle brackets.
Anybody got an idea?
Thanks in advance
You work can work that out in the __repr__ of the class.
As a simple example for an empty Deque instance:
>>> class Deque(object):
... def __repr__(self):
... return 'Deque<>'
...
>>> d = Deque()
>>> d
Deque<>
For a non-empty instance, you would simply format the returned string to include the contents of the instance.
You need to define the __repr__() method; you can return a string formatted however you want.
Related
I was looking into how the order in which you declare classes to inherit from affects Method Resolution Order (Detailed Here By Raymond Hettinger). I personally was using this to elegantly create an Ordered Counter via this code:
class OrderedCounter(Counter, OrderedDict):
pass
counts = OrderedCounter([1, 2, 3, 1])
print(*counts.items())
>>> (1, 2) (2, 1) (3, 1)
I was trying to understand why the following didn't work similarly:
class OrderedCounter(OrderedDict, Counter):
pass
counts = OrderedCounter([1, 2, 3, 1])
print(*counts.items())
>>> TypeError: 'int' object is not iterable
While I understand that on a fundamental level this is because the OrderedCounter object is using the OrderedDict.__init__() function in the second example which according to the documentation only accepts "[items]". In the first example however the Counter.__init__() function is used which according to the documentation accepts "[iterable-or-mapping]" thus it can take the list as an input.
I wanted to further understand this interaction specifically though so I went to look at the actual source. When I looked at the OrderedDict.__init__() function I noticed that after some error handling it made a call to self.update(*args, **kwds). However, the code simply has the line update = MutableMapping.update which I can't find much documentation on.
I guess I would just like a more concrete answer as to why the second code block doesn't work.
Note: For context, I have a decent amount of programming experience but I'm new to python and OOP in Python
TLDR: How/Why does the Method Resolution Order interfere with the second code block?
In your second example, class OrderedCounter(OrderedDict, Counter): the object looks in OrderedDict first which uses the update method from MutableMapping.
MutableMapping is an Abstract Base Class in collections._abc. Its update method source is here. You can see that if the other argument is not a mapping it will try to iterate over other unpacking a key and value on each iteration.
for key, value in other:
self[key] = value
If other is a sequence of tuples it would work.
>>> other = ((1,2),(3,4))
>>> for key,value in other:
print(key,value)
1 2
3 4
>>>
But if other is a sequence of single items it will throw the error when it tries to unpack a single value into two names/variables.
>>> other = (1,2,3,4)
>>> for key,value in other:
print(key,value)
Traceback (most recent call last):
File "<pyshell#50>", line 1, in <module>
for key,value in other:
TypeError: cannot unpack non-iterable int object
>>>
Whearas collections.Counter's update method calls a different function if other is not a Mapping.
else:
_count_elements(self, iterable)
_count_elements adds keys for new items (with a count of zero) or adds one to the count of existing keys.
As you probably discovered if a class inherits from two classes it will look in the first class to find an attribute, if it isn't there it will look in the second class.
>>> class A:
def __init__(self):
pass
def f(self):
print('class A')
>>> class B:
def __init__(self):
pass
def f(self):
print('class B')
>>> class C(A,B):
pass
>>> c = C()
>>> c.f()
class A
>>> class D(B,A):
pass
>>> d = D()
>>> d.f()
class B
In mro, children precede their parents and the order of appearance in __bases__ is respected.
In the first example, Counter is a subclass of dict. When OrderedDict is provided along with Counter, the parent dict of Counter is replaced by OrderedDict and the code works seamlessly.
In the second example, OrderedDict is again a subclass of dict. When Counter is provided along with OrderedDict, it tries to replace the parent dict of OrderedDict with Counter, which is counter intuitive (pun intended). Hence the error!!
I hope this layman explaination helps you. Just think about that for a moment.
I'm quite new in Python. I suppose my question is simple, but I don't find any answer. I would like to create, delete a composed list (as a C struct) and access items inside:
for i in list1
create item in list2[list3[StringVar1, StringVar2], bool1, Frame1]
item.list3[StringVar1] = i
item.list3[StringVar2] = value
item.bool1 = True
item.Frame1 = tk.Frame(self)
How can I write that in Python?
Edit: Martijn Pieters is right, I've just corrected.
I don't exactly understand by what you mean when you say composed list, but indeed you can have a struct in Python.
Ideally, you mean that you want an immutable C-Struct like object then, you can create it quite easily. In Python its called a namedtuple, or atleast this is the closest that I have come across. You can of course create your own generic object in Python, and add arguments, but that would be a dynamic struct instead.
Ideally, in C, you would have a struct like this ->
struct tag_name
{
type attribute;
type attribute2;
/* ... */
};
And you could access the attributes of the struct like so tag_name.attribute. So, this is how a namedtuple works:
>>> from collections import namedtuple
>>> NetworkAddress = namedtuple('NetworkAddress',['hostname','port'])
>>> a = NetworkAddress('www.python.org',80)
>>> a.hostname
'www.python.org'
>>> a.port
80
>>> host, port = a
>>> len(a)
2
>>> type(a)
<class '_ _main_ _.NetworkAddress'>
>>> isinstance(a, tuple)
True
>>>
If there is anything that you would like in specific, then please update your question to explain composed list so that I can update this answer.
However, this is typical of a statically typed language like C, since we're using Python, we can use some cool dynamic properties, so you an essentially create an object that you can add properties to as you see fit:
class DynamicObject(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
Console session
>>> class DynamicObject(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
>>> happy_obj = DynamicObject(name="Happy Gilmore")
>>> happy_obj.name
'Happy Gilmore'
Credits ->
https://stackoverflow.com/users/320726/6502 for the dynamic object code. Thanks man :)
You can always use a Python dictionary
item = {}
item["list2"] = {}
item["list2"]["list3"] = {}
item["list2"]["list3"][Var1] = Value1
item["list2"]["list3"][Var2] = Value2
...
You can assign another dictionary or a list as a value as well.
As far as delete is concerned you can use the "del" keyword to delete. For ex
dictionary = {}
dictionary["name"] = {}
dictionary["name1"] = {}
del dictionary["name1"]
dictionary
{'name': {}}
You should know that new style objects (anything derived from object) have a __dict__ member, which is a dict. So you can do:
class X(object):
pass
x = X()
x.__dict__["a"] = 1
x.a #1
another way to do this is to user setattr and getattr:
setattr(x, "b", 2) # same as x.__dict__["b"] = 2
You can use this to build named access to some input structure, however you will need names and values in your compound input structure (essentially, something like nested dicts for all nodes that are to have named children)
However, I think your data struct is wrong. For the use method is like array like in c. That means we can find elem by the number index, so you can't use list like list3[StringVar1,StringVar2].
Maybe the dictionary in python can meet your need. If you want to use item.list3 you must define a class in python.
I have a class, and I would like to be able to create multiple objects of that class and place them in an array. I did it like so:
rooms = []
rooms.append(Object1())
...
rooms.append(Object4())
I then have a dict of functions, and I would like to pass the object to the function. However, I'm encountering some problems..For example, I have a dict:
dict = {'look': CallLook(rooms[i])}
I'm able to pass it into the function, however; in the function if I try to call an objects method it gives me problems
def CallLook(current_room)
current_room.examine()
I'm sure that there has to be a better way to do what I'm trying to do, but I'm new to Python and I haven't seen a clean example on how to do this. Anyone have a good way to implement a list of objects to be passed into functions? All of the objects contain the examine method, but they are objects of different classes. (I'm sorry I didn't say so earlier)
The specific error states: TypeError: 'NoneType' object is not callable
Anyone have a good way to implement a list of objects to be passed into functions? All of the objects contain the examine method, but they are objects of different classes. (I'm sorry I didn't say so earlier)
This is Python's plain duck-typing.
class Room:
def __init__(self, name):
self.name = name
def examine(self):
return "This %s looks clean!" % self.name
class Furniture:
def __init__(self, name):
self.name = name
def examine(self):
return "This %s looks comfortable..." % self.name
def examination(l):
for item in l:
print item.examine()
list_of_objects = [ Room("Living Room"), Furniture("Couch"),
Room("Restrooms"), Furniture("Bed") ]
examination(list_of_objects)
Prints:
This Living Room looks clean!
This Couch looks comfortable...
This Restrooms looks clean!
This Bed looks comfortable...
As for your specific problem: probably you have forgotten to return a value from examine()? (Please post the full error message (including full backtrace).)
I then have a dict of functions, and I would like to pass the object to the function. However, I'm encountering some problems..For example, I have a dict:
my_dict = {'look': CallLook(rooms[i])} # this is no dict of functions
The dict you have created may evaluate to {'look': None} (assuming your examine() doesn't return a value.) Which could explain the error you've observed.
If you wanted a dict of functions you needed to put in a callable, not an actual function call, e.g. like this:
my_dict = {'look': CallLook} # this is a dict of functions
if you want to bind the 'look' to a specific room you could redefine CallLook:
def CallLook(current_room)
return current_room.examine # return the bound examine
my_dict = {'look': CallLook(room[i])} # this is also a dict of functions
Another issue with your code is that you are shadowing the built-in dict() method by naming your local dictionary dict. You shouldn't do this. This yields nasty errors.
Assuming you don't have basic problems (like syntax errors because the code you have pasted is not valid Python), this example shows you how to do what you want:
>>> class Foo():
... def hello(self):
... return 'hello'
...
>>> r = [Foo(),Foo(),Foo()]
>>> def call_method(obj):
... return obj.hello()
...
>>> call_method(r[1])
'hello'
Assuming you have a class Room the usual way to create a list of instances would be using a list comprehension like this
rooms = [Room() for i in range(num_rooms)]
I think there are some things you may not be getting about this:
dict = {'look': CallLook(rooms[i])}
This creates a dict with just one entry: a key 'look', and a value which is the result of evaluating CallLook(rooms[i]) right at the point of that statement. It also then uses the name dict to store this object, so you can no longer use dict as a constructor in that context.
Now, the error you are getting tells us that rooms[i] is None at that point in the programme.
You don't need CallLook (which is also named non-standardly) - you can just use the expression rooms[i].examine(), or if you want to evaluate the call later rooms[i].examine.
You probably don't need the dict at all.
That is not a must, but in some cases, using hasattr() is good... getattr() is another way to get an attribute off an object...
So:
rooms = [Obj1(),Obj2(),Obj3()]
if hasattr(rooms[i], 'examine'):#First check if our object has selected function or attribute...
getattr(rooms[i], 'examine') #that will just evaluate the function do not call it, and equals to Obj1().examine
getattr(rooms[i], 'examine')() # By adding () to the end of getattr function, we evalute and then call the function...
You may also pass parameters to examine function like:
getattr(rooms[i], 'examine')(param1, param2)
I'm not sure of your requirement, but you can use dict to store multiple object of a class.
May be this will help,
>>> class c1():
... print "hi"
...
hi
>>> c = c1()
>>> c
<__main__.c1 instance at 0x032165F8>
>>> d ={}
>>> for i in range (10):
... d[i] = c1()
...
>>> d[0]
<__main__.c1 instance at 0x032166E8>
>>> d[1]
<__main__.c1 instance at 0x032164B8>
>>>
It will create a object of c1 class and store it in dict. Obviously, in this case you can use list instead of dict.
I have the following piece of code:
NameX.functionA(functionB(Dictionary["___"]))
Instead of _ I would like to make a reference to NameX in the form of a string, so that the program interprets it as
NameX.functionA(functionB(Dictionary["NameX"]))
How can I do this? I tried to use str(self), but it is clearly wrong.
Thanks
Is NameX.__name__ perhaps what you want?
You can use
Name.__name__
on an uninitialized object and
Name.__class__.__name__
on an initialized object.
Abusive but it works:
>>> def getvarname(var):
d = globals()
for n in d:
if d[n] is var:
return n
return None
>>> class NameX: pass
>>> getvarname(NameX)
'NameX'
Works on things that aren't just classes, too:
>>> inst1 = NameX()
>>> getvarname(inst1)
'inst1'
You might be shot if this ends up in real code, though.
This question already has answers here:
How to print instances of a class using print()?
(12 answers)
Closed 7 months ago.
Well this interactive python console snippet will tell everything:
>>> class Test:
... def __str__(self):
... return 'asd'
...
>>> t = Test()
>>> print(t)
asd
>>> l = [Test(), Test(), Test()]
>>> print(l)
[__main__.Test instance at 0x00CBC1E8, __main__.Test instance at 0x00CBC260,
__main__.Test instance at 0x00CBC238]
Basically I would like to get three asd string printed when I print the list. I have also tried pprint but it gives the same results.
Try:
class Test:
def __repr__(self):
return 'asd'
And read this documentation link:
The suggestion in other answers to implement __repr__ is definitely one possibility. If that's unfeasible for whatever reason (existing type, __repr__ needed for reasons other than aesthetic, etc), then just do
print [str(x) for x in l]
or, as some are sure to suggest, map(str, l) (just a bit more compact).
You need to make a __repr__ method:
>>> class Test:
def __str__(self):
return 'asd'
def __repr__(self):
return 'zxcv'
>>> [Test(), Test()]
[zxcv, zxcv]
>>> print _
[zxcv, zxcv]
Refer to the docs:
object.__repr__(self)
Called by the repr() built-in function and by string conversions (reverse quotes) to compute the “official” string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form <...some useful description...> should be returned. The return value must be a string object. If a class defines __repr__() but not __str__(), then __repr__() is also used when an “informal” string representation of instances of that class is required.
This is typically used for debugging, so it is important that the representation is information-rich and unambiguous.