How do I intercept operations via subclassing? - python

I'm working through Learning Python 4th Edition and I'm currently working on the exercises for part VI of the book. The exercise I'm currently on is kind of confusing me and I was hoping I could get a little guidance as to how I can solve it.
Here's the prompt I'm working with.
Subclassing. Make a subclass of MyList from exercise 2 called MyListSub, which extends MyList to print a message to stdout before each overloaded operation is called and counts the number of calls. MyListSub should inherit basic method behavior from MyList. Adding a sequence to a MyListSub should print a message, increment the counter for + calls, and perform the superclass’s method. Also, introduce a new method that prints the operation counters to stdout, and experiment with your class interactively. Do your counters count calls per instance, or per class (for all instances of the class)? How would you program the other option)? (Hint: it depends on which object the count members are assigned to: class members are shared by instances, but self members are per-instance data.)
So the part I'm really interested in right now is the
Make a subclass of MyList from exercise 2 called MyListSub, which extends MyList to print a message to stdout before each overloaded operation is called and counts the number of calls.
I can see a good use of DRY right here that'll kill all my birds with one stone. But I just don't know how to implement it.
I know that what I should do is implement some kind of method that intercepts operations, increments a counter and prints a message. But I don't know how to best go about that. My basic idea is something like
def count_ops(self, op_count):
# intercept calls to operator overloading methods
op_count += 1
print 'Number of calls to operator {0}: {1}'.format(oper, op_count)
(Note: This isn't code I've written yet, this is borderline pseudocode to highlight what I want to do.)
Can I get a little help here? Please don't give me the answer outright I want to figure this out and hints go much further than answers. :)

Hint:
def count(cls):
for attr in (attr for attr in dir(cls) if not attr.startswith('_')):
method = getattr(cls,attr)
if callable(method):
setattr(cls,attr,func_count(method,attr))
return cls

Are your overloaded methods doing anything else besides counting the calls? In other words, do you have to write them anyway? If yes, you could use decorators, or just a seperate function like the one have and call it from each method.
If the only overloading needed in the subclass is the counting you can look into __getattribute__. Be warned -- it's a bit complicated, and you will want a thorough understanding of it before you ever used it in production code. Other options include a class decorator or a metaclass to wrap each of the methods you care about.

Related

What is the interpreter looking for?

I never realized just how poor a programmer I was until I came across this exercise below. I am to write a Python file that allows all of the tests below to pass without error.
I believe the file I write needs to be a class, but I have absolutely no idea what should be in my class. I know what the question is asking, but not how to make classes or to respond to the calls to the class with the appropriate object(s).
Please review the exercise code below, and then see my questions at the end.
File with tests:
import unittest
from allergies import Allergies
class AllergiesTests(unittest.TestCase):
def test_ignore_non_allergen_score_parts(self):
self.assertEqual(['eggs'], Allergies(257).list)
if __name__ == '__main__':
unittest.main()
1) I don't understand the "list" method at the end of this assertion. Is it the the Built-In Python function "list()," or is it an attribute that I need to define in my "Allergies" class?
2) What type of object is "Allergies(257).list"
self.assertEqual(['eggs'], Allergies(257).list)
3) Do I approach this by defining something like the following?
def list(self):
list_of_allergens = ['eggs','pollen','cat hair', 'shellfish']
return list_of_allergens[0]
1) I don't understand the "list" method at the end of this assertion. Is it the the Built-In Python function "list()," or is it an attribute that I need to define in my "Allergies" class?
From the ., you can tell that it's an attribute that you need to define on your Allergies class—or, rather, on each of its instances.*
2) What type of object is "Allergies(257).list"
Well, what is it supposed to compare equal to? ['eggs'] is a list of strings (well, of string). So, unless you're going to create a custom type that likes to compare equal to lists, you need a list.
3) Do I approach this by defining something like the following?
def list(self):
list_of_allergens = ['eggs','pollen','cat hair', 'shellfish']
return ist_of_allergens
No. You're on the wrong track right off the bat. This will make Allergies(257).list into a method. Even if that method returns a list when it's called, the test driver isn't calling it. It has to be a list. (Also, more obviously, ['eggs','pollen','cat hair', 'shellfish'] is not going to compare equal to ['eggs'], and ist_of_allergens isn't the same thing as list_of_allergens.)
So, where is that list going to come from? Well, your class is going to need to assign something to self.list somewhere. And, since the only code from your class that's getting called is your constructor (__new__) and initializer (__init__), that "somewhere" is pretty limited. And you probably haven't learned about __new__ yet, which means you have a choice of one place, which makes it pretty simple.
* Technically, you could use a class attribute here, but that seems less likely to be what they're looking for. For that matter, Allergies doesn't even have to be a class; it could be a function that just defines a new type on the fly, constructs it, and adds list to its dict. But both PEP 8 naming standards and "don't make things more complex for no good reason" both point to wanting a class here.
From how it's used, list is an attribute of the object returned by Allergies, which may be a function that returns an object or simply the call to construct an object of type Allergies. In this last case, the whole thing can be easily implemented as:
class Allergies:
def __init__(self, n):
# probably you should do something more
# interesting with n
if n==257:
self.list=['eggs']
This looks like one of the exercises from exercism.io.
I have completed the exercise, so I know what's involved.
'list' is supposed to be a class attribute of the class Allergies, and is itself an object of type list. At least that's one straight-forward way of dealing with it. I defined it in the __init__ method of the class. In my opinion, it's confusing that they called it 'list', as this clashes with Pythons list type.
snippet from my answer:
class Allergies(object):
allergens = ["eggs", "peanuts",
"shellfish", "strawberries",
"tomatoes", "chocolate",
"pollen","cats"]
def __init__(self, score):
# score_breakdown returns a list
self.list = self.score_breakdown(score) # let the name of this function be a little clue ;)
If I were you I would go and do some Python tutorials. I would start with basics, even if it feels like you are covering ground you already travelled. It's absolutely worth knowing your basics/fundamentals as solidly as possible. For this, I could recommend Udacity or codeacademy.

Is it common/good practice to test for type values in Python?

Is it common in Python to keep testing for type values when working in a OOP fashion?
class Foo():
def __init__(self,barObject):
self.bar = setBarObject(barObject)
def setBarObject(barObject);
if (isInstance(barObject,Bar):
self.bar = barObject
else:
# throw exception, log, etc.
class Bar():
pass
Or I can use a more loose approach, like:
class Foo():
def __init__(self,barObject):
self.bar = barObject
class Bar():
pass
Nope, in fact it's overwhelmingly common not to test for type values, as in your second approach. The idea is that a client of your code (i.e. some other programmer who uses your class) should be able to pass any kind of object that has all the appropriate methods or properties. If it doesn't happen to be an instance of some particular class, that's fine; your code never needs to know the difference. This is called duck typing, because of the adage "If it quacks like a duck and flies like a duck, it might as well be a duck" (well, that's not the actual adage but I got the gist of it I think)
One place you'll see this a lot is in the standard library, with any functions that handle file input or output. Instead of requiring an actual file object, they'll take anything that implements the read() or readline() method (depending on the function), or write() for writing. In fact you'll often see this in the documentation, e.g. with tokenize.generate_tokens, which I just happened to be looking at earlier today:
The generate_tokens() generator requires one argument, readline, which must be a callable object which provides the same interface as the readline() method of built-in file objects (see section File Objects). Each call to the function should return one line of input as a string.
This allows you to use a StringIO object (like an in-memory file), or something wackier like a dialog box, in place of a real file.
In your own code, just access whatever properties of an object you need, and if it's the wrong kind of object, one of the properties you need won't be there and it'll throw an exception.
I think that it's good practice to check input for type. It's reasonable to assume that if you asked a user to give one data type they might give you another, so you should code to defend against this.
However, it seems like a waste of time (both writing and running the program) to check the type of input that the program generates independent of input. As in a strongly-typed language, checking type isn't important to defend against programmer error.
So basically, check input but nothing else so that code can run smoothly and users don't have to wonder why they got an exception rather than a result.
If your alternative to the type check is an else containing exception handling, then you should really consider duck typing one tier up, supporting as many objects with the methods you require from the input, and working inside a try.
You can then except (and except as specifically as possible) that.
The final result wouldn't be unlike what you have there, but a lot more versatile and Pythonic.
Everything else that needed to be said about the actual question, whether it's common/good practice or not, I think has been answered excellently by David's.
I agree with some of the above answers, in that I generally never check for type from one function to another.
However, as someone else mentioned, anything accepted from a user should be checked, and for things like this I use regular expressions. The nice thing about using regular expressions to validate user input is that not only can you verify that the data is in the correct format, but you can parse the input into a more convenient form, like a string into a dictionary.

Have well-defined, narrowly-focused classes ... now how do I get anything done in my program?

I'm coding a poker hand evaluator as my first programming project. I've made it through three classes, each of which accomplishes its narrowly-defined task very well:
HandRange = a string-like object (e.g. "AA"). getHands() returns a list of tuples for each specific hand within the string:
[(Ad,Ac),(Ad,Ah),(Ad,As),(Ac,Ah),(Ac,As),(Ah,As)]
Translation = a dictionary that maps the return list from getHands to values that are useful for a given evaluator (yes, this can probably be refactored into another class).
{'As':52, 'Ad':51, ...}
Evaluator = takes a list from HandRange (as translated by Translator), enumerates all possible hand matchups and provides win % for each.
My question: what should my "domain" class for using all these classes look like, given that I may want to connect to it via either a shell UI or a GUI? Right now, it looks like an assembly line process:
user_input = HandRange()
x = Translation.translateList(user_input)
y = Evaluator.getEquities(x)
This smells funny in that it feels like it's procedural when I ought to be using OO.
In a more general way: if I've spent so much time ensuring that my classes are well defined, narrowly focused, orthogonal, whatever ... how do I actually manage work flow in my program when I need to use all of them in a row?
Thanks,
Mike
Don't make a fetish of object orientation -- Python supports multiple paradigms, after all! Think of your user-defined types, AKA classes, as building blocks that gradually give you a "language" that's closer to your domain rather than to general purpose language / library primitives.
At some point you'll want to code "verbs" (actions) that use your building blocks to perform something (under command from whatever interface you'll supply -- command line, RPC, web, GUI, ...) -- and those may be module-level functions as well as methods within some encompassing class. You'll surely want a class if you need multiple instances, and most likely also if the actions involve updating "state" (instance variables of a class being much nicer than globals) or if inheritance and/or polomorphism come into play; but, there is no a priori reason to prefer classes to functions otherwise.
If you find yourself writing static methods, yearning for a singleton (or Borg) design pattern, writing a class with no state (just methods) -- these are all "code smells" that should prompt you to check whether you really need a class for that subset of your code, or rather whether you may be overcomplicating things and should use a module with functions for that part of your code. (Sometimes after due consideration you'll unearth some different reason for preferring a class, and that's allright too, but the point is, don't just pick a class over a module w/functions "by reflex", without critically thinking about it!).
You could create a Poker class that ties these all together and intialize all of that stuff in the __init__() method:
class Poker(object):
def __init__(self, user_input=HandRange()):
self.user_input = user_input
self.translation = Translation.translateList(user_input)
self.evaluator = Evaluator.getEquities(x)
# and so on...
p = Poker()
# etc, etc...

Should I use a class in this: Reading a XML file using lxml

This question is in continuation to my previous question, in which I asked about passing around an ElementTree.
I need to read the XML files only and to solve this, I decided to create a global ElementTree and then parse it wherever required.
My question is:
Is this an acceptable practice? I heard global variables are bad. If I don't make it global, I was suggested to make a class. But do I really need to create a class? What benefits would I have from that approach. Note that I would be handling only one ElementTree instance per run, the operations are read-only. If I don't use a class, how and where do I declare that ElementTree so that it available globally? (Note that I would be importing this module)
Please answer this question in the respect that I am a beginner to development, and at this stage I can't figure out whether to use a class or just go with the functional style programming approach.
There are a few reasons that global variables are bad. First, it gets you in the habit of declaring global variables which is not good practice, though in some cases globals make sense -- PI, for instance. Globals also create problems when you on purpose or accidentally re-use the name locally. Or worse, when you think you're using the name locally but in reality you're assigning a new value to the global variable. This particular problem is language dependent, and python handles it differently in different cases.
class A:
def __init__(self):
self.name = 'hi'
x = 3
a = A()
def foo():
a.name = 'Bedevere'
x = 9
foo()
print x, a.name #outputs 3 Bedevere
The benefit of creating a class and passing your class around is you will get a defined, constant behavior, especially since you should be calling class methods, which operate on the class itself.
class Knights:
def __init__(self, name='Bedevere'):
self.name = name
def knight(self):
self.name = 'Sir ' + self.name
def speak(self):
print self.name + ":", "Run away!"
class FerociousRabbit:
def __init__(self):
self.death = "awaits you with sharp pointy teeth!"
def speak(self):
print "Squeeeeeeee!"
def cave(thing):
thing.speak()
if isinstance(thing, Knights):
thing.knight()
def scene():
k = Knights()
k2 = Knights('Launcelot')
b = FerociousRabbit()
for i in (b, k, k2):
cave(i)
This example illustrates a few good principles. First, the strength of python when calling functions - FerociousRabbit and Knights are two different classes but they have the same function speak(). In other languages, in order to do something like this, they would at least have to have the same base class. The reason you would want to do this is it allows you to write a function (cave) that can operate on any class that has a 'speak()' method. You could create any other method and pass it to the cave function:
class Tim:
def speak(self):
print "Death awaits you with sharp pointy teeth!"
So in your case, when dealing with an elementTree, say sometime down the road you need to also start parsing an apache log. Well if you're doing purely functional program you're basically hosed. You can modify and extend your current program, but if you wrote your functions well, you could just add a new class to the mix and (technically) everything will be peachy keen.
Pragmatically, is your code expected to grow? Even though people herald OOP as the right way, I found that sometimes it's better to weigh cost:benefit(s) whenever you refactor a piece of code. If you are looking to grow this, then OOP is a better option in that you can extend and customise any future use case, while saving yourself from unnecessary time wasted in code maintenance. Otherwise, if it ain't broken, don't fix it, IMHO.
I generally find myself regretting it when I give in to the temptation to give a module, for example, a load_file() method that sets a global that the module's other functions can then use to find the file they're supposed to be talking about. It makes testing far more difficult, for example, and as soon as I need two XML files there is a problem. Plus, every single function needs to check whether the file's there and give an error if it's not.
If I want to be functional, I simply therefore have every function take the XML file as an argument.
If I want to be object oriented, I'll have a MyXMLFile class whose methods can just look at self.xmlfile or whatever.
The two approaches are more or less equivalent when there's just one single thing, like a file, to be passed around; but when the number of things in the "state" becomes larger than a few, then I find classes simpler because I can stick all of those things in the class.
(Am I answering your question? I'm still a big vague on what kind of answer you want.)

Why isn't the 'len' function inherited by dictionaries and lists in Python

example:
a_list = [1, 2, 3]
a_list.len() # doesn't work
len(a_list) # works
Python being (very) object oriented, I don't understand why the 'len' function isn't inherited by the object.
Plus I keep trying the wrong solution since it appears as the logical one to me
Guido's explanation is here:
First of all, I chose len(x) over x.len() for HCI reasons (def __len__() came much later). There are two intertwined reasons actually, both HCI:
(a) For some operations, prefix notation just reads better than postfix — prefix (and infix!) operations have a long tradition in mathematics which likes notations where the visuals help the mathematician thinking about a problem. Compare the easy with which we rewrite a formula like x*(a+b) into x*a + x*b to the clumsiness of doing the same thing using a raw OO notation.
(b) When I read code that says len(x) I know that it is asking for the length of something. This tells me two things: the result is an integer, and the argument is some kind of container. To the contrary, when I read x.len(), I have to already know that x is some kind of container implementing an interface or inheriting from a class that has a standard len(). Witness the confusion we occasionally have when a class that is not implementing a mapping has a get() or keys() method, or something that isn’t a file has a write() method.
Saying the same thing in another way, I see ‘len‘ as a built-in operation. I’d hate to lose that. /…/
The short answer: 1) backwards compatibility and 2) there's not enough of a difference for it to really matter. For a more detailed explanation, read on.
The idiomatic Python approach to such operations is special methods which aren't intended to be called directly. For example, to make x + y work for your own class, you write a __add__ method. To make sure that int(spam) properly converts your custom class, write a __int__ method. To make sure that len(foo) does something sensible, write a __len__ method.
This is how things have always been with Python, and I think it makes a lot of sense for some things. In particular, this seems like a sensible way to implement operator overloading. As for the rest, different languages disagree; in Ruby you'd convert something to an integer by calling spam.to_i directly instead of saying int(spam).
You're right that Python is an extremely object-oriented language and that having to call an external function on an object to get its length seems odd. On the other hand, len(silly_walks) isn't any more onerous than silly_walks.len(), and Guido has said that he actually prefers it (http://mail.python.org/pipermail/python-3000/2006-November/004643.html).
It just isn't.
You can, however, do:
>>> [1,2,3].__len__()
3
Adding a __len__() method to a class is what makes the len() magic work.
This way fits in better with the rest of the language. The convention in python is that you add __foo__ special methods to objects to make them have certain capabilities (rather than e.g. deriving from a specific base class). For example, an object is
callable if it has a __call__ method
iterable if it has an __iter__ method,
supports access with [] if it has __getitem__ and __setitem__.
...
One of these special methods is __len__ which makes it have a length accessible with len().
Maybe you're looking for __len__. If that method exists, then len(a) calls it:
>>> class Spam:
... def __len__(self): return 3
...
>>> s = Spam()
>>> len(s)
3
Well, there actually is a length method, it is just hidden:
>>> a_list = [1, 2, 3]
>>> a_list.__len__()
3
The len() built-in function appears to be simply a wrapper for a call to the hidden len() method of the object.
Not sure why they made the decision to implement things this way though.
there is some good info below on why certain things are functions and other are methods. It does indeed cause some inconsistencies in the language.
http://mail.python.org/pipermail/python-dev/2008-January/076612.html

Categories