Like in ruby we have module which can be included in any given class and then we can use the methods defined there, this saves us from inheritance which is considered as a coupling. In python is there any way to replicate same functionality? For eg I have two classes
class A:
pass
class B:
pass
I want to have both of the above two classes to have logging functionality which may be like:
def log(message):
print message
In Python, we generally just go ahead and use inheritance for this. It's essentially a mixin pattern.
You can use modules, though, if you really want to:
class Foo(object):
def __init__(self):
pass
from methods import baz, bar, quux
Here methods.py would be a module containing functions (or other attributes) named baz, bar, and quux, and possibly others. As shown, you can go ahead and define methods directly on the class as well.
Using a wildcard import gives you a warning in Python 2.7 and I believe it's disallowed entirely in Python 3.x:
class Foo(object):
from methods import *
So, as usual in Python, "explicit is better than implicit." That is, specify exactly which methods you want in your class instead of saying "give me all of them." It makes your code much clearer.
Related
I have currently this structure inside a file:
class Foo:
__init__(self):
pass
class FooType(object):
__init__(self, value):
_foo = value
__str__(self):
print ">>%s<<" % self._foo
class FooException(Exception):
pass
All the above classes are tightly related. My master class will have types, structures, enums all declared as a separated class with the prefix Foo. And as usual a custom exception should be declared for Foo. At the end of the day I will have a lot of related classes at the same level of other classes.
Is there a proper way to get a better structure? Perhaps a namespace can help, but I don't know how to use it.
In Python, the idiomatic way to do namespaces is to use different modules. You should name your file foo.py, and then import that. Then you use it with foo.Exception and foo.Type. If you need to have a more complex module that needs more than one file, you should make a folder called foo and put an __init__.py file along with your other components of the module. For further documentation on using modules, see the docs.
Another solution is to use nested classes to provide a namespace. The chosen answer to this question about nested classes recommends them for the purpose of namespacing.
You could organize your classes in modules, just like the Python standard library does.
I have two classes which are different in most aspects but they share a common method. I would like to call this method(which belongs to class A) from within class B:
It would be something like this:
class classA():
def m():
pass
class classB():
classB_instance = classB()
classB_instance.m() #here I would like to call a method m() which belongs to class A
I know its possible to inherit this method from classA, however I don't want to use inheritance here, because classA has other methods which have nothing to do with classB.
However, I would be happy to use "a restricted inheritance". What I mean here is... I would like to inherit this method only, but leave the other methods/attributes intact.
Is that possible in Python?
You could use a mixin class:
class MixIn(object):
def m(self):
pass
class classA(MixIn): pass
class classB(MixIn): pass
Note that using mixins works fine for small projects but they do not scale well to large projects. See Mixins considered harmful (part 1), (part2), (part3), (part4). Those articles point out a number of issues, including:
namespace pollution
insufficient separation of concerns
fragility with respect to name clashes
complication of the MRO
non-scalability of the design
conceptual confusion with the isa relationship
Even if mixins work fine for small projects, it's not good to encourage their use if they don't scale well, since small projects may grow into large projects (despite the best intentions of the author :-) ).
#mgilson's answer may be better since its explicitness avoids the hard-to-trace/namespace-pollution issue. But it is still vulnerable to many of the other issues mentioned above.
So, alternatively, using polymorphic functions might suit your needs:
def m(self): pass
class classA(object): pass
class classB(object): pass
a = classB()
b = classB()
m(a)
m(b)
As your project grows, if m's behavior depends on the type of its argument, you can extend m without needing to change the syntax by using generic functions (see also PEP443).
Another, better approach is to use composition instead of inheritance. See the interface wrapper solution for example.
You can write a regular function and just put it into your classes namespace:
>>> def _m(self):
... print "Hello World"
...
>>> class Foo(object):
... m = _m
...
>>> class Bar(object):
... m = _m
...
>>> Foo().m()
Hello World
>>> Bar().m()
Hello World
This might not be quite as DRY as the mixin proposed by others, but it does keep your inheritance trees completely separate.
I have a one to many class inheritance structure as follows:
class SuperClass:
def func1():
print 'hello'
def func2():
print 'ow'
class SubClass1(SuperClass):
def func1():
print 'hi'
class SubClass2(SuperClass):
def func1():
print 'howdy'
...
I want to add functionality to class A so that I can use it when I create classes B and C (etc), but I cannot edit the code for class A directly. My current solution is:
def func3():
print 'yes!'
SuperClass.func3 = func3
Is there a better and/or more pythonic way to achieve this?
This is called "monkeypatching", and is perfectly reasonable in some cases.
For example if you have to use someone else's code (that you can't modify) that depends on SuperClass, and you need to change that code's behavior, your only real choice is to replace methods on SuperClass.
However, in your case, there doesn't seem to be any good reason to do this. You're defining all of the subclasses of SuperClass, so why not just add another class in between?
class Intermediate(SuperClass):
def func3():
pass
class SubClass1(Intermediate):
def func1():
print 'hi'
This isn't good enough for "functionality that should have been in SuperClass but wasn't" if other code you can't control needs that functionality… but when it's only your code that needs that functionality, it's just as good, and a lot simpler.
If even the subclasses aren't under your control, often you can just derive a new class from each one that is. For example:
class Func3Mixin(object):
def func3():
pass
class F3SubClass1(SubClass1, Func3Mixin):
pass
class F3SubClass2(SubClass2, Func3Mixin):
pass
Now you just construct instances of F3SubClass1 instead of SubClass1. Code that was expecting a SubClass1 instance can use an F3SubClass1 just fine. And Python's duck typing makes this kind of "mixin-oriented programming" especially simple: inside the implementation of Func3Mixin.func3, you can use attributes and methods of SuperClass, despite the fact that Func3Mixin itself isn't statically related to SuperClass in any way, because you know that any runtime object that is a Func3Mixin will also be a SuperClass.
Meanwhile, even when monkeypatching is appropriate, it isn't necessarily the best answer. For example, if you're patching to work around a bug in some third-party code, that code has a nice license and a source repository that makes it easy to maintain your own patches, you can just fork it, create a fixed copy, and use that instead of the original.
Also, it's worth pointing out that none of your classes are actually usable as written—any attempt to call any of the methods will raise a TypeError because they're missing the self argument. But the way you've monkeypatched in func3, it will fail in exactly the same way as func1. (And the same is true for the alternatives I sketched above.)
Finally, all of your classes here are classic classes rather than new-style, because you forgot to make SuperClass inherit from object. If you can't change SuperClass, of course, that's not your fault—but you may want to fix it anyway by making your subclasses (or Intermediate) multiply inherit from object and SuperClass. (If you've been paying attention: yes, this means you can mix-in new-style-classness. Although under the covers you have to understand metaclasses to understand why.)
Python classes have no concept of public/private, so we are told to not touch something that starts with an underscore unless we created it. But does this not require complete knowledge of all classes from which we inherit, directly or indirectly? Witness:
class Base(object):
def __init__(self):
super(Base, self).__init__()
self._foo = 0
def foo(self):
return self._foo + 1
class Sub(Base):
def __init__(self):
super(Sub, self).__init__()
self._foo = None
Sub().foo()
Expectedly, a TypeError is raised when None + 1 is evaluated. So I have to know that _foo exists in the base class. To get around this, __foo can be used instead, which solves the problem by mangling the name. This seems to be, if not elegant, an acceptable solution. However, what happens if Base inherits from a class (in a separate package) called Sub? Now __foo in my Sub overrides __foo in the grandparent Sub.
This implies that I have to know the entire inheritance chain, including all "private" objects each uses. The fact that Python is dynamically-typed makes this even harder, since there are no declarations to search for. The worst part, however, is probably the fact Base might inherit from object right now, but in some future release, it switches to inheriting from Sub. Clearly if I know Sub is inherited from, I can rename my class, however annoying that is. But I can't see into the future.
Is this not a case where a true private data type would prevent a problem? How, in Python, can I be sure that I'm not accidentally stepping on somebody's toes if those toes might spring into existence at some point in the future?
EDIT: I've apparently not made clear the primary question. I'm familiar with name mangling and the difference between a single and a double underscore. The question is: how do I deal with the fact that I might clash with classes whose existence I don't know of right now? If my parent class (which is in a package I did not write) happens to start inheriting from a class with the same name as my class, even name mangling won't help. Am I wrong in seeing this as a (corner) case that true private members would solve, but that Python has trouble with?
EDIT: As requested, the following is a full example:
File parent.py:
class Sub(object):
def __init__(self):
self.__foo = 12
def foo(self):
return self.__foo + 1
class Base(Sub):
pass
File sub.py:
import parent
class Sub(parent.Base):
def __init__(self):
super(Sub, self).__init__()
self.__foo = None
Sub().foo()
The grandparent's foo is called, but my __foo is used.
Obviously you wouldn't write code like this yourself, but parent could easily be provided by a third party, the details of which could change at any time.
Use private names (instead of protected ones), starting with a double underscore:
class Sub(Base):
def __init__(self):
super(Sub, self).__init__()
self.__foo = None
# ^^
will not conflict with _foo or __foo in Base. This is because Python replaces the double underscore with a single underscore and the name of the class; the following two lines are equivalent:
class Sub(Base):
def x(self):
self.__foo = None # .. is the same as ..
self._Sub__foo = None
(In response to the edit:) The chance that two classes in a class hierarchy not only have the same name, but that they are both using the same property name, and are both using the private mangled (__) form is so minuscule that it can be safely ignored in practice (I for one haven't heard of a single case so far).
In theory, however, you are correct in that in order to formally verify correctness of a program, one most know the entire inheritance chain. Luckily, formal verification usually requires a fixed set of libraries in any case.
This is in the spirit of the Zen of Python, which includes
practicality beats purity.
Name mangling includes the class so your Base.__foo and Sub.__foo will have different names. This was the entire reason for adding the name mangling feature to Python in the first place. One will be _Base__foo, the other _Sub__foo.
Many people prefer to use composition (has-a) instead of inheritance (is-a) for some of these very reasons.
This implies that I have to know the entire inheritance chain. . .
Yes, you should know the entire inheritance chain, or the docs for the object you are directly sub-classing should tell you what you need to know.
Subclassing is an advanced feature, and should be treated with care.
A good example of docs specifying what should be overridden in a subclass is the threading class:
This class represents an activity that is run in a separate thread of control. There are two ways to specify the activity: by passing a callable object to the constructor, or by overriding the run() method in a subclass. No other methods (except for the constructor) should be overridden in a subclass. In other words, only override the __init__() and run() methods of this class.
How often do you modify base classes in inheritance chains to introduce inheritance from a class with the same name as a subclass further down the chain???
Less flippantly, yes, you have to know the code you are working with. You certainly have to know the public names being used, after all. Python being python, discovering the public names in use by your ancestor classes takes pretty much the same effort as discovering the private ones.
In years of Python programming, I have never found this to be much of an issue in practice. When you're naming instance variables, you should have a pretty good idea whether (a) a name is generic enough that it's likely to be used in other contexts and (b) the class you're writing is likely to be involved in an inheritance hierarchy with other unknown classes. In such cases, you think a bit more carefully about the names you're using; self.value isn't a great idea for an attribute name, and neither is something like Adaptor a great class name.
In contrast, I have run into difficulties with the overuse of double-underscore names a number of times. Python being Python, even "private" names tend to be accessed by code defined outside the class. You might think that it would always be bad practice to let an external function access "private" attributes, but what about things like getattr and hasattr? The invocation of them can be in the class's own code, so the class is still controlling all access to the private attributes, but they still don't work without you doing the name-mangling manually. If Python had actually-enforced private variables you couldn't use functions like those on them at all. These days I tend to reserve double-underscore names for cases when I'm writing something very generic like a decorator, metaclass, or mixin that needs to add a "secret attribute" to the instances of the (unknown) classes it's applied to.
And of course there's the standard dynamic language argument: the reality is that you have to test your code thoroughly to have much justification in making the claim "my software works". Such testing will be very unlikely to miss the bugs caused by accidentally clashing names. If you are not doing that testing, then many more uncaught bugs will be introduced by other means than by accidental name clashes.
In summation, the lack of private variables is just not that big a deal in idiomatic Python code in practice, and the addition of true private variables would cause more frequent problems in other ways IMHO.
Mangling happens with double underscores. Single underscores are more of a "please don't".
You don't need to know all the details of all parent classes (note that deep inheritance is usually best avoided), because you can still dir() and help() and any other form of introspection you can come up with.
As noted, you can use name mangling. However, you can stick with a single underscore (or none!) if you document your code adequately - you should not have so many private variables that this proves to be a problem. Just say if a method relies on a private variable, and add either the variable, or the name of the method to the class docstring to alert users.
Further, if you create unit tests, you should create tests that check invariants on members, and accordingly these should be able to show up such name clashes.
If you really want to have "private" variables, and for whatever reason name-mangling doesn't meet your needs, you can factor your private state into another object:
class Foo(object):
class Stateholder(object): pass
def __init__(self):
self._state = Stateholder()
self.state.private = 1
I'm developing a PyQT4 application, and it's getting pretty hard for me to navigate through all of the code at once. I know of the import foo statement, but I can't figure out how to make it import a chunk of code directly into my script, like the BASH source foo statement.
I'm trying to do this:
# File 'functions.py'
class foo(asd.fgh):
def __init__(self):
print 'foo'
Here is the second file.
# File 'main.py'
import functions
class foo(asd.fgh):
def qwerty(self):
print 'qwerty'
I want to include code or merge class decelerations from two separate files. In PHP, there is import_once('foo.php'), and as I mentioned previously, BASH has source 'foo.sh', but can I accomplish this with Python?
Thanks!
For some reason, my first thought was multiple inheritance. But why not try normal inheritance?
class foo(functions.foo):
# All of the methods that you want to add go here.
Is there some reason that this wont work?
Since you just want to merge class definitions, why don't you do:
# main.py
import functions
# All of the old stuff that was in main.foo is now in this class
class fooBase(asd.fgh):
def qwerty(self):
print 'qwerty'
# Now create a class that has methods and attributes of both classes
class foo(FooBase, functions.foo): # Methods from FooBase take precedence
pass
or
class foo(functions.foo, FooBase): # Methods from functions.foo take precedence
pass
This takes advantage of pythons capability for multiple inheritance to create a new class with methods from both sources.
You want execfile(). Although you really don't, since redefining a class, uh... redefines it.
monkey patching in python doesn't work in nearly the same way. This is normally considered poor form, but if you want to do it anyways, you can do this:
# File 'functions.py'
class foo(asd.fgh):
def __init__(self):
print 'foo'
the imported module remains unchanged. In the importing module, we do things quite differently.
# File 'main.py'
import functions
def qwerty(self):
print 'qwerty'
functions.foo.qwerty = qwerty
Note that there is no additional class definition, just a bare function. we then add the function as an attribute of the class.