What does Python return when instantiating new classes?
I'm finding loads of quirks with Python when instantiating a new class. I'm sure it's just because I'm not used to the language, but even so, the behaviour I can see is really strange.
If I open up iPython and type the following:
class Person:
def __init__(self, name):
self.name = name
def hello(self):
print "Hello, " + self.name
Everything works exactly as I'd expect it to:
In [2]: Person
Out[2]: <class __main__.Person at 0x1c97330>
In [3]: p = Person("Jamie")
In [4]: p
Out[4]: <__main__.Person instance at 0x1c90b98>
In [5]: p.hello()
Hello, Jamie
However, if I then access a separate class inside package - nothing too fancy, I might add - and instantiate a new class, it all goes wrong. Here's the link to the code for palestrina/cache.py
In [6]: from palestrina.cache import Cache
In [7]: Cache
Out[7]: <class palestrina.cache.Cache at 0x1c97750>
In [8]: c = Cache(application = 'example', backend = 'filesystem')
In [9]: c
Out[9]: ---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/Users/jamierumbelow/Sites/Os/palestrina/<ipython console> in <module>()
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/IPython/Prompts.pyc in __call__(self, arg)
550
551 # and now call a possibly user-defined print mechanism
--> 552 manipulated_val = self.display(arg)
553
554 # user display hooks can change the variable to be stored in
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/IPython/Prompts.pyc in _display(self, arg)
576 return IPython.generics.result_display(arg)
577 except TryNext:
--> 578 return self.shell.hooks.result_display(arg)
579
580 # Assign the default display method:
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/IPython/hooks.pyc in __call__(self, *args, **kw)
139 #print "prio",prio,"cmd",cmd #dbg
140 try:
--> 141 ret = cmd(*args, **kw)
142 return ret
143 except ipapi.TryNext, exc:
/Library/Frameworks/Python.fr开发者_运维问答amework/Versions/2.6/lib/python2.6/site-packages/IPython/hooks.pyc in result_display(self, arg)
169
170 if self.rc.pprint:
--> 171 out = pformat(arg)
172 if '\n' in out:
173 # So that multi-line strings line up with the left column of
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/pprint.pyc in pformat(self, object)
109 def pformat(self, object):
110 sio = _StringIO()
--> 111 self._format(object, sio, 0, 0, {}, 0)
112 return sio.getvalue()
113
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/pprint.pyc in _format(self, object, stream, indent, allowance, context, level)
127 self._readable = False
128 return
--> 129 rep = self._repr(object, context, level - 1)
130 typ = _type(object)
131 sepLines = _len(rep) > (self._width - 1 - indent - allowance)
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/pprint.pyc in _repr(self, object, context, level)
221 def _repr(self, object, context, level):
222 repr, readable, recursive = self.format(object, context.copy(),
--> 223 self._depth, level)
224 if not readable:
225 self._readable = False
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/pprint.pyc in format(self, object, context, maxlevels, level)
233 and whether the object represents a recursive construct.
234 """
--> 235 return _safe_repr(object, context, maxlevels, level)
236
237
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/pprint.pyc in _safe_repr(object, context, maxlevels, level)
318 return format % _commajoin(components), readable, recursive
319
--> 320 rep = repr(object)
321 return rep, (rep and not rep.startswith('<')), False
322
TypeError: 'bool' object is not callable
I can't understand what is going on here. Can someone explain to me what might be happening?
Thanks.
Well, you removed the relevant part (the traceback) and replaced it by ...
in your paste.
But it looks like you have an error in the representation of the class.
Here's a simulation of the error:
>>> class MyClass(object):
... def __repr__(self):
... return True()
...
>>> c = MyClass()
>>> c
Please check the traceback you removed and you'll see what is happening exactly. If you can't, please edit your question and include it, so we can explain further.
Providing the source code of that class would also help.
Not Python's fault, your package is causing the trouble.
You use some nasty tricks to save typing. Specifically, you're overriding the special __getattr__
method, which is used whenever you try to access an attribute of c
. Inspecting it will look for a __repr__
method, and methods are attributes, so...
Trying to entirely replace the attributes of your class for convenience is a really bad idea. I think you'd be better off doing it with __getitem__
, __setitem__
and __delitem__
, so your cache access looks like c["name"]
rather than c.name
.
EDIT: Another tip, try not to catch all your errors unless you've got something productive to do instead. If you hadn't been catching keyerrors on get()
and turning them into return False
, the traceback would have shown exactly what it was trying to do. And what if I wanted to store True or False in the cache? How do I know whether False means False or "value missing"?
精彩评论