Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I'm currently implementing the Factory design pattern in Python and I have a few questions.
Is there any way to prevent the direct instantiation of the actual concrete classes? For example, if I have a VehicleFactory that spawns Vehicles, I want users to just use that factory, and prevent anyone from accidentally instantiating Car() or Truck() directly. I can throw an exception in init() perhaps, but that would also mean that the factory can't create an instance of it...
It seems to me now that factories are getting addictive. Seems like everything should become a factory so that when I change internal implementation, the client codes will not change. I'm interested to know when is there an actual need to use factories, and when is it not appropriate to use. For example, I might have a Window class and there's only one of this type now (no PlasticWindow, ReinforcedWindow or anything like that). In that case, should I use a factory for the client to generate the Window, just in case I might add more types of Windows in the future?
I'm just wondering if there is a usual way of calling the factories. For example, now I'm calling my Vehicle factory as Vehicles, so the codes will go something like Vehicles.create(...). I see a lot of tutorials doing it like VehicleFactory, but I find it too long and it sort of exposes the implementation as well.
EDIT: What I meant by "exposes the implementation" is that it lets people know that it's a factory. What I felt was that the client need not know that it's a factory, but rather as some class that can return objects for you (which is a factory of course but maybe there's no need to explicitly tell clients that?). I know that the soure codes are easily exposed, so I didn't mean "exposing the way the functionalities are implemented in the source codes".
Thanks!
Be Pythonic. Don't overcomplicate your code with "enterprise" language (like Java) solutions that add unnecessary levels of abstraction.
Your code should be simple, and intuitive. You shouldn't need to delegate to another class to instantiate another.
Don't expose the class (for example make it private __MyClass, or obvious that you don't want it used directly _MyClass). This way it can only be instantiated via the factory function.
Perhaps you should review the use of keyword arguments, and inheritance. It sounds like you may be overlooking these, which will generally reduce your dependence on complex factories (To be honest, I've rarely needed factories).
In Python you cannot easily protect against exposing implementation, it goes against the Zen of Python. (It's the same in any language, a determined individual can get what they want eventually). At most you should try to ensure that a user of your code does not accidentally do the wrong thing, but never presume to know what the end-user may decide to achieve with your code. Don't make it obfuscated and difficult to work with.
Is there any way to prevent the direct instantiation of the actual concrete classes?
Why? Are your programmers evil sociopaths who refuse to follow the rules? If you provide a factory -- and the factory does what people need -- then they'll use the factory.
You can't "prevent" anything. Remember. This is Python -- they have the source.
should I use a factory for the client to generate the Window, just in case I might add more types of Windows in the future?
Meh. Neither good nor bad. It can get cumbersome to manage all the class-hierarchy-and-factory details.
Adding a factory isn't hard. This is Python -- you have all the source at all times -- you can use grep to find a class constructor and replace it with a factory when you need to.
Since you can use grep to find and fix your mistakes, you don't need to pre-plan this kind of thing as much as you might in Java or C++.
I see a lot of tutorials doing it like VehicleFactory, but I find it too long and it sort of exposes the implementation as well.
"Too Long"? It's used so rarely that it barely matters. Use long names -- it helps other folks understand what you're doing. This is not Code Golf where fewest keystrokes wins.
"exposes the implementation"? First, It exposes nothing. Second, this is Python -- you have all the source at all times -- everything is already exposed.
Stop thinking so much about prevention and privacy. It isn't helpful.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
So, I'm developing a simple web-scraper in Python right now, but I had a question on how to structure my code. In other programming languages (especially compiled languages like C++ and C#), I've been in the habit of wrapping all of my functions in classes. I.e. in my web-scraping example I would have a class called something like "WebScraper" maybe and then hold all of the functions within that class. I might even go so far as to create a second helper class like "WebScraperManager" if I needed to instantiate multiple instances of the original "WebScraper" class.
This leads me to my current question, though. Would similiar logic hold in the current example? Or would I simply define a WebScraper.py file, without a wrapper class inside that file, and then just import the functions as I needed them into some main.py file?
The difference between a class and a function should be that a class has state. Some classes don't have state, but this is rarely a good idea (I'm sure there's exceptions, abstract base classes (ABCs) for instance but I'm not sure if they count), and some functions do have state, but this is rarely a good idea (caching or instrumentation might be exceptions).
If you want an URL as input, and say a dict as output, and then you are done with that website, there's no reason to have a class. Just have a function that takes an URL and returns a dict. Stateless functions are simpler abstractions than classes, so all other things being equal, prefer them.
However, very often there may be intermediate state involved. For instance, maybe you are scraping a family of pages rooted in a base URL, and it's too expensive to do all this eagerly. Maybe then what you want is a class that takes the root URL as its constructor. It then has some methods for querying which child URLs it can follow down, and methods for ordering subsequent scraping of children, which might be stored in nested data structures.
And of course, if your task is reasonably complicated, you may well have layers with functions using classes, or classes calling function. But persisting state is a good indicator of whether the immediate task should be written as a class or set of functions.
Edit: just to close the loop and come round to the original question: No, I would say it's not pythonesque to wrap all functions in classes. Free functions are just fine in python, it all depends what's appropriate. Also, the term pythonesque is not very pythonic ;-)
You mean "pythonic".
That depends in how much Object Oriented, scalable... do you want your implementation. I would use class over simple functions. Lets says tomorrow you want an CraiglistScraper and a FacebookScraper... I would create an abstract class "Scraper " and then the two above inherit from this one and reimplement what you need (Polymorphism). I mean the Object Oriented Principles and Patterns are language independent. Now I wouldn't "hold all the functions" in a class (Single responsibility principle), every time you code remember this word "SOLID".
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Perhaps I am dated on my information, but I was going to help someone learn an OOP language, concepts, etc. I wanted to use something dynamic. My thought was Python but then I read it has no Interfaces. Isn't an Interface something someone needs to know to learn OOP concepts?
My thought was Python but then I read it has no Interfaces.
Well, you can use interfaces in Python. The standard library has the abc module, and there are third-party modules like PyProtocols (and frameworks like Zope and Twisted have their own similar ideas).
The point is that they aren't required, and frequently aren't even necessary. You "wanted to use something dynamic"? That's what it means to be dynamic: Functions take any object with the right interface, without needing that interface to be statically defined anywhere, much less needing the object to statically declare that it supports the interface.
So, when you ask:
Isn't an Interface something someone needs to know to learn OOP concepts?
The answer is "No". An Interface is something someone needs to know to learn Java-style OOP, but it's not something someone needs to know to learn OOP in general.
Consider this from a different angle: It's possible, but not easy, to do Javascript-style OOP in Python; as in Java, classes are too fundamental to Python to live without. Does that make Python and Java bad OO languages and Javascript a good one? No; it just makes them different OO languages.
monkut wanted to know "wtf is an interface???"
An interface (aka protocol, abstract base class, abstract type, …) is just a type that can be used for static and/or dynamic type checking and/or switching in exactly same way a class can.
So, what's the good of that? Well, in theory, you should never need to inspect types—that's not just part of the Zen of Python, it's part of core OO dogma as well—but in practice sometimes you do. So, being able to name your abstract types, and declare that a class supports a variety of different abstract types, can be useful.
Of course you could do that with plain old classes, but being able to explicitly declare that a type is abstract can also help with readability and debugging. PEP 3119 explains the rationale in a Python-centric way.
But in languages like Java, there's are two additional benefits.
First, if you have static type checking, you can't write a single function that can take, e.g., a list, a tuple, a set, a frozenset, or an iterator. But you can write a function that takes an Iterable, and then declare that list, tuple, etc. all provide the Iterable interface, and then everything is fine. (In a language with dynamic type checking, duck typing already takes care of this for you—your code works with any object that has an __iter__ method that returns something that behaves the way you expect it to.)
Second, if you've got static data member layout and/or vtable-style method override mechanism, multiple inheritance is very tricky. But multiple inheritance is also very useful. So in Java, an interface is something just like a class, but with no data members or method implementations, and you can inherit from as many interfaces as you want, but only one class. This gives Java some of the benefits of multiple inheritance, without any of the problems. (In a language with dynamic data members and dynamic method lookup, as long as you have a sensible MRO algorithm, as Python does, you can get all of the benefits of multiple inheritance without any of the problems.)
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Much of my programming background is in Java, and I'm still doing most of my programming in Java. However, I'm starting to learn Python for some side projects at work, and I'd like to learn it as independent of my Java background as possible - i.e. I don't want to just program Java in Python. What are some things I should look out for?
A quick example - when looking through the Python tutorial, I came across the fact that defaulted mutable parameters of a function (such as a list) are persisted (remembered from call to call). This was counter-intuitive to me as a Java programmer and hard to get my head around. (See here and here if you don't understand the example.)
Someone also provided me with this list, which I found helpful, but short. Anyone have any other examples of how a Java programmer might tend to misuse Python...? Or things a Java programmer would falsely assume or have trouble understanding?
Edit: Ok, a brief overview of the reasons addressed by the article I linked to to prevent duplicates in the answers (as suggested by Bill the Lizard). (Please let me know if I make a mistake in phrasing, I've only just started with Python so I may not understand all the concepts fully. And a disclaimer - these are going to be very brief, so if you don't understand what it's getting at check out the link.)
A static method in Java does not translate to a Python classmethod
A switch statement in Java translates to a hash table in Python
Don't use XML
Getters and setters are evil (hey, I'm just quoting :) )
Code duplication is often a necessary evil in Java (e.g. method overloading), but not in Python
(And if you find this question at all interesting, check out the link anyway. :) It's quite good.)
Don't put everything into classes. Python's built-in list and dictionaries will take you far.
Don't worry about keeping one class per module. Divide modules by purpose, not by class.
Use inheritance for behavior, not interfaces. Don't create an "Animal" class for "Dog" and "Cat" to inherit from, just so you can have a generic "make_sound" method.
Just do this:
class Dog(object):
def make_sound(self):
return "woof!"
class Cat(object):
def make_sound(self):
return "meow!"
class LolCat(object):
def make_sound(self):
return "i can has cheezburger?"
The referenced article has some good advice that can easily be misquoted and misunderstood. And some bad advice.
Leave Java behind. Start fresh. "do not trust your [Java-based] instincts". Saying things are "counter-intuitive" is a bad habit in any programming discipline. When learning a new language, start fresh, and drop your habits. Your intuition must be wrong.
Languages are different. Otherwise, they'd be the same language with different syntax, and there'd be simple translators. Because there are not simple translators, there's no simple mapping. That means that intuition is unhelpful and dangerous.
"A static method in Java does not translate to a Python classmethod." This kind of thing is really limited and unhelpful. Python has a staticmethod decorator. It also has a classmethod decorator, for which Java has no equivalent.
This point, BTW, also included the much more helpful advice on not needlessly wrapping everything in a class. "The idiomatic translation of a Java static method is usually a module-level function".
The Java switch statement in Java can be implemented several ways. First, and foremost, it's usually an if elif elif elif construct. The article is unhelpful in this respect. If you're absolutely sure this is too slow (and can prove it) you can use a Python dictionary as a slightly faster mapping from value to block of code. Blindly translating switch to dictionary (without thinking) is really bad advice.
Don't use XML. Doesn't make sense when taken out of context. In context it means don't rely on XML to add flexibility. Java relies on describing stuff in XML; WSDL files, for example, repeat information that's obvious from inspecting the code. Python relies on introspection instead of restating everything in XML.
But Python has excellent XML processing libraries. Several.
Getters and setters are not required in Python they way they're required in Java. First, you have better introspection in Python, so you don't need getters and setters to help make dynamic bean objects. (For that, you use collections.namedtuple).
However, you have the property decorator which will bundle getters (and setters) into an attribute-like construct. The point is that Python prefers naked attributes; when necessary, we can bundle getters and setters to appear as if there's a simple attribute.
Also, Python has descriptor classes if properties aren't sophisticated enough.
Code duplication is often a necessary evil in Java (e.g. method overloading), but not in Python. Correct. Python uses optional arguments instead of method overloading.
The bullet point went on to talk about closure; that isn't as helpful as the simple advice to use default argument values wisely.
One thing you might be used to in Java that you won't find in Python is strict privacy. This is not so much something to look out for as it is something not to look for (I am embarrassed by how long I searched for a Python equivalent to 'private' when I started out!). Instead, Python has much more transparency and easier introspection than Java. This falls under what is sometimes described as the "we're all consenting adults here" philosophy. There are a few conventions and language mechanisms to help prevent accidental use of "unpublic" methods and so forth, but the whole mindset of information hiding is virtually absent in Python.
The biggest one I can think of is not understanding or not fully utilizing duck typing. In Java you're required to specify very explicit and detailed type information upfront. In Python typing is both dynamic and largely implicit. The philosophy is that you should be thinking about your program at a higher level than nominal types. For example, in Python, you don't use inheritance to model substitutability. Substitutability comes by default as a result of duck typing. Inheritance is only a programmer convenience for reusing implementation.
Similarly, the Pythonic idiom is "beg forgiveness, don't ask permission". Explicit typing is considered evil. Don't check whether a parameter is a certain type upfront. Just try to do whatever you need to do with the parameter. If it doesn't conform to the proper interface, it will throw a very clear exception and you will be able to find the problem very quickly. If someone passes a parameter of a type that was nominally unexpected but has the same interface as what you expected, then you've gained flexibility for free.
The most important thing, from a Java POV, is that it's perfectly ok to not make classes for everything. There are many situations where a procedural approach is simpler and shorter.
The next most important thing is that you will have to get over the notion that the type of an object controls what it may do; rather, the code controls what objects must be able to support at runtime (this is by virtue of duck-typing).
Oh, and use native lists and dicts (not customized descendants) as far as possible.
The way exceptions are treated in Python is different from
how they are treated in Java. While in Java the advice
is to use exceptions only for exceptional conditions this is not
so with Python.
In Python things like Iterator makes use of exception mechanism to signal that there are no more items.But such a design is not considered as good practice in Java.
As Alex Martelli puts in his book Python in a Nutshell
the exception mechanism with other languages (and applicable to Java)
is LBYL (Look Before You Leap) :
is to check in advance, before attempting an operation, for all circumstances that might make the operation invalid.
Where as with Python the approach is EAFP (it's easier to Ask for forgiveness than permission)
A corrollary to "Don't use classes for everything": callbacks.
The Java way for doing callbacks relies on passing objects that implement the callback interface (for example ActionListener with its actionPerformed() method). Nothing of this sort is necessary in Python, you can directly pass methods or even locally defined functions:
def handler():
print("click!")
button.onclick(handler)
Or even lambdas:
button.onclick(lambda: print("click!\n"))
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
We need to write simple scripts to manipulate the configuration of our load balancers (ie, drain nodes from pools, enabled or disable traffic rules). The load balancers have a SOAP API (defined through a bunch of WSDL files) which is very comprehensive but using it is quite low-level with a lot of manual error checking and list manipulation. It doesn't tend to produce reusable, robust code.
I'd like to write a Python library to handle the nitty-gritty of interacting with the SOAP interface but I don't really know where to start; all of my coding experience is with writing one-off monolithic programs for specific jobs. This is fine for small jobs but it's not helping me or my coworkers -- we're reinventing the wheel with a different number of spokes each time :~)
The API already provides methods like getPoolNames() and getDrainingNodes() but they're a bit awkward to use. Most take a list of nodes and return another list, so (say) working out which virtual servers are enabled involves this sort of thing:
names = conn.getVirtualServerNames()
enabled = conn.getEnabled(names)
for i in range(0, len(names)):
if (enabled[i]):
print names[i]
conn.setEnabled(['www.example.com'], [0])
Whereas something like this:
lb = LoadBalancer('hostname')
for name in [vs.name for vs in lb.virtualServers() if vs.isEnabled()]:
print name
www = lb.virtualServer('www.example.com').disable()
is more Pythonic and (IMHO) easier.
There are a lot of things I'm not sure about: how to handle errors, how to deal with 20-odd WSDL files (a SOAPpy/suds instance for each?) and how much boilerplate translation from the API methods to my methods I'll need to do.
This is more an example of a wider problem (how to learn to write libraries instead of one-off scripts) so I don't want answers to these specific questions -- they're there to demonstrate my thinking and illustrate my problem. I recognise a code smell in the way I do things at the moment (one-off, non-reusable code) but I don't know how to fix it. How does one get into the mindset for tackling problems at a more abstract level? How do you 'learn' software design?
"I don't really know where to start"
Clearly false. You provided an excellent example. Just do more of that. It's that simple.
"There are a lot of things I'm not sure about: how to handle errors, how to deal with 20-odd WSDL files (a SOAPpy/suds instance for each?) and how much boilerplate translation from the API methods to my methods I'll need to do."
Handle errors by raising an exception. That's enough. Remember, you're still going to have high-level scripts using your API library.
20-odd WSDL files? Just pick something for now. Don't overengineer this. Design the API -- as you did with your example -- for the things you want to do. The WSDL's and the number of instances will become clear as you go. One, Ten, Twenty doesn't really matter to users of your API library. It only matters to you, the maintainer. Focus on the users.
Boilerplate translation? As little as possible. Focus on what parts of these interfaces you use with your actual scripts. Translate just what you need and nothing more.
An API is not fixed, cast in concrete, a thing of beauty and a joy forever. It's just a module (in your case a package might be better) that does some useful stuff.
It will undergo constant change and evolution.
Don't overengineer the first release. Build something useful that works for one use case. Then add use cases to it.
"But what if I realize I did something wrong?" That's inevitable, you'll always reach this point. Don't worry about it now.
The most important thing about writing an API library is writing the unit tests that (a) demonstrate how it works and (b) prove that it actually works.
There's an excellent presentation by Joshua Bloch on API design (and thus leading to library design). It's well worth watching. IIRC it's Java-focused, but the principles will apply to any language.
If you are not afraid of C++, there is an excellent book on the subject called "Large-scale C++ Software Design".
This book will guide you through the steps of designing a library by introducing "physical" and "logical" design.
For instance, you'll learn to flatten your components' hierarchy, to restrict dependency between components, to create levels of abstraction.
The is really "the" book on software design IMHO.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
So I'm starting a project using Python after spending a significant amount of time in static land. I've seen some projects that make "interfaces" which are really just classes without any implementations. Before, I'd scoff at the idea and ignore that section of those projects. But now, I'm beginning to warm up to the idea.
Just so we're clear, an interface in Python would look something like this:
class ISomething(object):
def some_method():
pass
def some_other_method(some_argument):
pass
Notice that you aren't passing self to any of the methods, thus requiring that the method be overriden to be called. I see this as a nice form of documentation and completeness testing.
So what is everyone here's opinion on the idea? Have I been brainwashed by all the C# programming I've done, or is this a good idea?
I'm not sure what the point of that is. Interfaces (of this form, anyway) are largely to work around the lack of multiple inheritance. But Python has MI, so why not just make an abstract class?
class Something(object):
def some_method(self):
raise NotImplementedError()
def some_other_method(self, some_argument):
raise NotImplementedError()
In Python 2.6 and later, you can use abstract base classes instead. These are useful, because you can then test to see if something implements a given ABC by using "isinstance". As usual in Python, the concept is not as strictly enforced as it would be in a strict language, but it's handy. Moreover there are nice idiomatic ways of declaring abstract methods with decorators - see the link above for examples.
There are some cases where interfaces can be very handy. Twisted makes fairly extensive use of Zope interfaces, and in a project I was working on Zope interfaces worked really well. Enthought's traits packaged recently added interfaces, but I don't have any experience with them.
Beware overuse though -- duck typing and protocols are a fundamental aspect of Python, only use interfaces if they're absolutely necessary.
The pythonic way is to "Ask for forgiveness rather than receive permission". Interfaces are all about receiving permission to perform some operation on an object. Python prefers this:
def quacker(duck):
try:
duck.quack():
except AttributeError:
raise ThisAintADuckException
I don't think interfaces would add anything to the code environment.
Method definition enforcing happens without them. If an object expected to be have like Foo and have method bar(), and it does't, it will throw an AttributeError.
Simply making sure an interface method gets defined doesn't guarantee its correctness; behavioral unit tests need to be in place anyway.
It's just as effective to write a "read this or die" page describing what methods your object needs to have to be compatible with what you're plugging it in as having elaborate docstrings in an interface class, since you're probably going to have tests for it anyway. One of those tests can be standard for all compatible objects that will check the invocation and return type of each base method.
Seems kind of unnecessary to me - when I'm writing classes like that I usually just make the base class (your ISomething) with no methods, and mention in the actual documentation which methods subclasses are supposed to override.
You can create an interface in a dynamically typed language, but there's no enforcement of the interface at compile time. A statically typed language's compiler will warn you if you forget to implement (or mistype!) a method of an interface. Since you receive no such help in a dynamically typed language, your interface declaration serves only as documentation. (Which isn't necessarily bad, it's just that your interface declaration provides no runtime advantage versus writing comments.)
I'm about to do something similar with my Python project, the only things I would add are:
Extra long, in-depth doc strings for each interface and all the abstract methods.
I would add in all the required arguments so there's a definitive list.
Raise an exception instead of 'pass'.
Prefix all methods so they are obviously part of the interface - interface Foo: def foo_method1()
I personally use interfaces a lot in conjunction with the Zope Component Architecture (ZCA). The advantage is not so much to have interfaces but to be able to use them with adapters and utilities (singletons).
E.g. you could create an adapter which can take a class which implements ISomething but adapts it to the some interface ISomethingElse. Basically it's a wrapper.
The original class would be:
class MyClass(object):
implements(ISomething)
def do_something(self):
return "foo"
Then imagine interface ISomethingElse has a method do_something_else(). An adapter could look like this:
class SomethingElseAdapter(object):
implements(ISomethingElse)
adapts(ISomething)
def __init__(self, context):
self.context = context
def do_something_else():
return self.context.do_something()+"bar"
You then would register that adapter with the component registry and you could then use it like this:
>>> obj = MyClass()
>>> print obj.do_something()
"foo"
>>> adapter = ISomethingElse(obj)
>>> print adapter.do_something_else()
"foobar"
What that gives you is the ability to extend the original class with functionality which the class does not provide directly. You can do that without changing that class (it might be in a different product/library) and you could simply exchange that adapter by a different implementation without changing the code which uses it. It's all done by registration of components in initialization time.
This of course is mainly useful for frameworks/libraries.
I think it takes some time to get used to it but I really don't want to live without it anymore. But as said before it's also true that you need to think exactly where it makes sense and where it doesn't. Of course interfaces on it's own can also already be useful as documentation of the API. It's also useful for unit tests where you can test if your class actually implements that interface. And last but not least I like starting by writing the interface and some doctests to get the idea of what I am actually about to code.
For more information you can check out my little introduction to it and there is a quite extensive description of it's API.
Glyph Lefkowitz (of Twisted fame) just recently wrote an article on this topic. Personally I do not feel the need for interfaces, but YMMV.
Have you looked at PyProtocols? it has a nice interface implementation that you should look at.