4 ms·
One concern I have with Jack Diederich's video is that he never addressed one benefit of classes: better testability. In his Muffin example, he took out the ins
by johnkchow 15y ago
One concern I have with Jack Diederich's video is that he never addressed one benefit of classes: better testability. In his Muffin example, he took out the instance variable that stored the API URL and created a constant out of it. If I had an URL for my staging environment, and another for my production environment, I'd like to programatically set that instead of going back into the code, modifying the constant value, run the test, and then change the value back to the original. That's just a bug waiting to happen.
This isn't to say his underlying message is wrong (I 100% agree with Jack's message, too much classes create unnecessary complexity in your library/app), but I don't want people destroying their classes without fully understanding the consequences.
- quotemstr 15y agoYou can create a variable, set that, and pass that variable as the first parameter to greeting. I don't see why having a class makes testing any easier.
- radicalbyte 15y agoDecoupling. For example if your code requires access to an outside resource (database, message queue, email service) you can mock said resource in order to test the code in isolation.
- skrebbel 15y agoHey! Ho! Stop that. Nobody uses the word "Decoupling", I just learned that in the video. You must be pulling a fast one on me.
- tmorton 15y agoLet me clarify what I think you're saying. It's not about testing class X, it's about testing code that uses class X. As long as X is a class, then we can create a mock version and pass around instances of it. If our "X functionality" is stored somewhere else (ie a bare function), then that gets harder.
- quotemstr 15y agoDown that road lies the hell of dependency injection frameworks. A simpler approach is to use something like detours[1] to mock bare functions directly. [1] https://research.microsoft.com/en-us/projects/detours/ https://research.microsoft.com/en-us/projects/detours/
- Drbble 15y agoGoogle Guice is not hell.
- densh 15y agoIn python you can mock pretty much anything you want. You can mock package-defined variables by simply modifying them to the value you want (sys.modules['mymodule'].MY_GLOBAL_SWITCH = True). In such a way you can even mock standard library functions and built-ins (which have their own __builtin__ package). With such capabilities you can test pretty much any code. (There are some limitations indeed, like you can't change types which are defined in C code.)
- johnkchow 15y agoI agree that in Jack's specific examples you don't need the constructor: the constructor trivially saves the parameters into instance variables. However, one thing that hasn't been mention is when the setup of the class is non-trivial, which most likely requires breaking it down its helper methods that's only specific to that class. Exposing those helper methods outside of the class can potentially add as much unnecessary complexity to the code base (i.e. is this a helper method for another method or if this is standalone method, how does this fit into what I'm trying to achieve?). Yes, this could be mitigated with good documentation, but classes exist for this specific reason.
- quotemstr 15y agoHuh? Modularity has nothing to do with classes. In plain C, your main "method" can be a simple external function, and the "helpers" can be static functions. Python offers similar functionality. Making a class is a step backward because the internal helpers have to exposed to users, even if they're intended not to be used.
- Drbble 15y agoExposed how? Methods can be private.
- j2labs 15y agoJust use a settings file. I use settings overrides by putting local_settings.py in my .gitignore and then adding this to the bottom of my settings.py: https://github.com/j2labs/microarmy/blob/master/settings.py#L52 https://github.com/j2labs/microarmy/blob/master/settings.py#...
- astrofinch 15y agoWhy are you masking errors from that import?
- tawhaki 15y agoI assume it is so that the default values are used if no local_settings.py file exists, instead of aborting the program with an uncaught ImportError.
- pjscott 15y agoIf so, then for the benefit of any Python newbies here: "except ImportError" is the idiomatic way to handle this situation, it it clearly communicates intent, and prevents masking legitimate errors. One fairly common pattern is to try to import one module, and if it's not installed, to go for a backup. For example, if I need to parse JSON, the simplejson library is significantly faster than the (completely API-compatible) standard library "json" module: try: import simplejson as json except ImportError: import json I'm pretty sure I've seen those exact four lines of code in the internals of Tornado and Flask, among others.
- mdonahoe 15y agoexplicit is better than implicit He should explicitly catch the ImportError
- tkahn6 15y agoWhy not just pass the url into each function where it needs to be used?
- winter_blue 15y agoUhh.. that's ugly redundant code. Classes make code neater and easier to read..
- tkahn6 15y agoNot really redundant when you can curry the function when needed. This is how libraries in functional languages are written. Classes make code harder to reason about given that you have hidden state everywhere.
- kingkilr 15y agoDo you think a closure isn't state?
- jrockway 15y agoHe does, but he feels smarter if he emulates something everyone already does in a more obscure manner. Yesterday, I derived an n-algebra for feeding my cat. See how smart I am!? (The reality is simple. Classes are Python's state-capture abstraction. Using a bunch of lambdas to do the same thing means you are writing Haskell in Python, which is a dumb thing to do, because while the computer knows what you want, other programmers don't. If you want to use Haskell, use Haskell.)
- deleted 15y ago[deleted]
- tkahn6 15y agoOuch. No need to be condescending, Jon. When I write Python, I use classes and magic methods and all that jazz. Programming in a functional style in Python is often verbose and brittle due to the duck-typing. I was under the impression we were talking about programming in general.