I am creating an interface for Python scripting.
Later I will be dong Python scripting also for automated testing.
Is it necessary the at i must use class in my code.Now I have created the code
with dictionaries,lists,functions,global and local variables.
Is class necessary?
Help me in this.
No, of course class is not a must. As Python is a scripting language, you can simply code your scripts without defining your own classes.
Classes are useful if you implement a more complex program which needs a structured approach and OOP benfits (encapsulation, polimorphism) help you in doing it.
It's not needed to make it work, but I would argue that it will become messy to maintain if you do not encapsulate certain things in classes. Classes are something that schould help the programmer to organizes his/her code, not just nice to have fluff.
No you don't need to use classes for scripting.
However, when you start using the unit testing framework unittest, that will involve classes so you need to understand at least how to sub-class the TestCase class, eg:
import unittest
import os
class TestLint(unittest.TestCase):
def testLintCreatesLog(self):
# stuff that does things to create the file lint.log removed...
assert os.path.exists('lint.log') # this should be here after lint
assert os.path.getsize('lint.log') == 0 # nothing in the log - assume happy
if __name__ == '__main__':
# When this module is executed from the command-line, run all its tests
unittest.main()
not necessary since python is not a purely object oriented language but certain things are better written in classes (encapsulation).it becomes easier to build a large project using classes
Related
I'm trying to import a function from a python module. That function is declared on the module I'm calling import from, but nevertheless I'm using that function on the other file.
Like so:
context.py
from elements import *
class Context:
def __init__(self):
pass
#staticmethod
def load():
print "load code here"
elements.py
from context import *
class Item:
def __init__(self):
Context.load() # NameError: global name 'load' is not defined
As someone who comes from Java, seems like applying the same nested class accessing logic doesn't work in Python. I'm wondering what could be the best practice here, since it doesn't seem right to put the import statement below the Context class. I searched about this but the material wasn't clear about this practice.
Also, at context.py I'm using instances of classes defined at elements, and vice versa. So my question is really what would be the best importing practice here.
Another related question: is it good practice to encapsulate functions and variables inside Classes in Python or should I use global functions/variables instead?
Ah, in Python this is considered a circular import error -- and can be incredibly frustrating. elements is importing from context and vice-versa. This may be possible in Java with magic compiler tricks but since Python is (mostly) interpreted, this isn't possible*.
Another unstated difference between Java and Python is that a Python class is closer to a hashmap with a special API than a proper Java class. As such, it is perfectly acceptable and preferable to put classes that have a tight interdependence (such as the ones you wrote) in the same Python module. This will remove the circular import error.
In general, you want to organize library modules by dependency level -- meaning, the leaves of your lib folder do not import from anything else in your project, and as you progress closer to the root, more imports are drawn upon. To the best of your ability you want your import structure to be a tree, not a spiderweb (if that makes any sense). Without a compiler, it's the only way I've found in a large (multi-million line) Python project to maintain sanity.
The above comments are generally considered best practice, this next suggestion is highly opinionated:
I would recommend structuring executable modules around I/O boundaries. It becomes very tempting to build tightly interconnected fabrics of Python objects with complicated inheritance structures passed by reference. While on a small and medium scale this offers development advantages, on a larger scale you lose the ability to easily integrate concurrency since you've taken away the ability for the code to be transfer-layer agnostic.
Edit: Okay, it IS possible by playing around with import statement ordering, using the __import__ method, etc., to hack the import framework and accomplish this. However, you should NOT do this if you intend to have a large project -- it is very brittle and difficult to explain to a team. It seems like you're more interested in best practices, which is how I directed my answer. Sorry if that was unclear.
In context.py file you should add def before __init__, also class methods do not take self:
class Context:
def __init__(self):
pass
#staticmethod
def load():
print "load code here"
then in another file:
from context import Context
class Item:
def __init__(self):
Context.load()
As I learn more about Python I am starting to get into the realm of classes. I have been reading on how to properly call a class and how to import the module or package.module but I was wondering if it is really needed to do this.
My question is this: Is it required to move your class to a separate module for a functional reason or is it solely for readability? I can perform all the same task using defined functions within my main module so what is the need for the class if any outside of readability?
Modules are structuring tools that provide encapsulation. In other words, modules are structures that combine your logic and data into one compartment, in the module itself. When you code a module, you should be consistent. To make a module consistent you must define its purpose: does my module provide tools? What type of tools? String tools? Numericals tools...?
For example, let's assume you're coding a program that processes numbers. Typically, you would use the builtin math module, and for some specialized purposes you might need to code some functions and classes that process your numbers according to your needs. If you read the documentation of math builtin module, you'll find math defines classes ad functions that relate to math but no classes or functions that process strings for instance, this is cohesion--unifying the purpose of your module. Keep in mind, maximizing cohesion, minimizes coupling. That's, when you keep your module unified, you make it less likely to be dependent on other modules.
Is it required to move your Class to a separate module for a functional reason or is it solely for readability?
If that specific class doesn't relate to your module, then you're probably better off moving that class to another module. Definitely, This is not a valid statement all the time. Suppose you're coding a relatively small program and you don't really need to define a large number of tools that you'll use in your small program, coding your class in your main module doesn't hurt at all. In larger applications where you need to write dozens of tools on the other hand, it's better to split your program to modules with specified purposes, myStringTools, myMath, main and many other modules. Structuring your program with modules and packages enhances maintenance.
If you need to delve deeper read about Modular programming, it'll help you grasp the idea even better.
You can do as you please. If the code for your classes is short, putting them all in your main script is fine. If they're longish, then splitting them out into separate files is a useful organizing technique (that has the added benefit of the code in them no getting recompiled into byte-code everytime the the script they are used in is run.
Putting them in modules also encourages their reuse since they're no longer mixed in with a lot of other unrelated stuff.
Lastly, they may be useful because modules are esstentially singleton objects, meaning that there's only once instance of them in your program which is created the first time it's imported. Later imports in other modules will just reuse the existing instance. This can be a nice way to do initialize that only has to be done once.
I'm rather new to unit-testing and am trying to feel out the best practices for the thing. I've seen several questions on here relating to unit-test inheriting a base class that itself contains several tests, for example:
class TestBase(unittest.TestCase):
# some standard tests
class AnotherTest(TestBase):
# run some more tests in addition to the standard tests
I think what I've gathered from the community is that it's a better idea to write separate tests for each implementation and use multiple inheritance. But what if that base class actually doesn't contain any tests - just helpers for all your other tests. For example, let's say I've got some base test class which I've used to store some common methods that most if not all of my other tests will use. Let's also assume that I've got a database model in models.py called ContentModel
test_base.py
import webtest
from google.appengine.ext import testbed
from models import ContentModel
class TestBase(unittest.TestCase):
def setUp(self):
self.ContentModel = ContentModel
self.testbed = testbed.Testbed()
self.testbed.activate()
# other useful stuff
def tearDown(self):
self.testbed.deactivate()
def createUser(self, admin=False):
# create a user that may or may not be an admin
# possibly other useful things
It seems this would save me tons of time on all other tests:
another_test.py
from test_base import TestBase
class AnotherTest(TestBase):
def test_something_authorized(self):
self.createUser(admin=True)
# run a test
def test_something_unauthorized(self):
self.createUser(admin=False)
# run a test
def test_some_interaction_with_the_content_model(self):
new_instance = self.ContentModel('foo' = 'bar').put()
# run a test
Note: this is based on some of my work in webapp2 on google app engine, but I expect that
an analogous situation arises for pretty much any python web application
My Question
Is it good practice to use a base/helper class that contains useful methods/variables which all your other tests inherit, or should each test class be "self contained"?
Thanks!
Superb question. I think that almost anything you do that automates testing is excellent. That said, the tests really serve as the only reliable source of documentation. So the tests should be very easy to read and comprehend. The tests are reliable, unlike comments, because they show what the software really does and how to use it.
I like this approach. But you might also try out nose. Nose is a bit "lighter weight" to set up, and is well supported if you go the continuous integration route with something like Jenkins for automated build/test/deployment. Nose does not format its messages quite as nicely as the xUnit style (IMO, of course). But for many things, you might be willing to give that up.
BTW. Python is not Java. So it is perfectly acceptable to reuse just a plain old python function for re-use.
A base class is a good option for some uses - as long as you don't test anything in the base class. I use base classes all the time.
Also, think of the value of seeing the code in your test class. A good example is a base class I use all the time (in c#.NET): I use a SDK - ArcObjects from Esri - that requires a license. In normal execution this is handled elsewhere, but in testing, I have to check out (or activate) a license before I can use the objects in the library. This has absolutely nothing to do with the functionality of the code I am testing in the test class, but is required to make the tests run. Thus, I decided to tuck this functionality away in a base class that check s out a license before a test and checks it back in after. Tests that requires a licence are simply inherriting from this base class.
Finally, be very careful about where you setup and tear down the prerequisites for the test. It can get messy if some is done in the base class and others are done in the child class.
I'm very new to Python (I'm coming from a JAVA background) and I'm wondering if anyone could help me with some of the Python standards. Is it a normal or "proper" practice to put multiple class in a module? I have been working with Django and started with the tutorials and they place their database model classes in the same module. Is this something that is normally done or should I stick with 1 class per module? Is there a reason I would do one over the other?
Hope I'm being clear and not to generic. Thanks to everyone in advance!
Here is a useful rule of thumb from what I have seen of typical Java projects:
The bottom-most package in Java should be a file in Python
What does that mean?
If your Java project was organized:
toplevel/
subproject/
Foo.java
Bar.java
subproject2/
Baz.java
Qux.java
Then your Python project should look like:
toplevel/
subproject.py <-- put class Foo, Bar here
subproject2.py <-- put class Baz, Qux here
Things to notice re: organization:
Do not use inner classes. Just put
classes in the same module
By convention, things that start with _ are "private"
It's OK to have "public variables"
Think it this way.
In java what you write is a Class where in the case of Python, you write a module instead of a class. So a module can contain several classes.
Whenever you want to use a particular class, import the respective module first and then call the class to make objects.
Here's an example.
Classes.py (This is a module named 'Classes')
class MyClass(object):
def greet(self):
print("Hello World")
class MyNextClass(object):
def greetAgain(self):
print("Hello again")
Now I can import this module from anywhere I wish
import Classes
if __name__ == '__main__':
a=Classes.MyClass()
a.greet()
b=Classes.MyNextClass()
b.greetAgain()
When in doubt, just look at Python's standard libraries :)
For example, the standard calendar module contains 31 classes. So yes, it is ok.
It is absolutely proper to do so. A module groups related functionality. If that functionality is implemented in several classes (e.g., Tree, Node, Leaf) then it is appropriate to place them together.
A module is more closely associated with a Java package than a Java class. You can also implement a module as a folder, named for the module, with an __init__.py file inside (so Python can identify the module as such; the __init__.py may also optionally include initialization code and lists of classes, functions, and sub-packages to export.)
It is certainly a normal thing to do in Python. When and why you choose one over the other is partly a matter of taste, and partly convention.
If you're still getting to know Python, and therefore its conventions, reading the style guide is well worth your time.
Would it be possible to create a class interface in python and various implementations of the interface.
Example: I want to create a class for pop3 access (and all methods etc.). If I go with a commercial component, I want to wrap it to adhere to a contract.
In the future, if I want to use another component or code my own, I want to be able to swap things out and not have things very tightly coupled.
Possible? I'm new to python.
For people coming from a strongly typed language background, Python does not need a class interface. You can simulate it using a base class.
class BaseAccess:
def open(arg):
raise NotImplementedError()
class Pop3Access(BaseAccess):
def open(arg):
...
class AlternateAccess(BaseAccess):
def open(arg):
...
But you can easily write the same code without using BaseAccess. Strongly typed language needs the interface for type checking during compile time. For Python, this is not necessary because everything is looked up dynamically in run time. Google 'duck typing' for its philosophy.
There is a Abstract Base Classes module added in Python 2.6. But I haven't have used it.
Of course. There is no need to create a base class or an interface in this case either, as everything is dynamic.
One option is to use zope interfaces. However, as was stated by Wai Yip Tung, you do not need to use interfaces to achieve the same results.
The zope.interface package is really more a tool for discovering how to interact with objects (generally within large code bases with multiple developers).
Yes, this is possible. There are typically no impediments to doing so: just keep a stable API and change how you implement it.