How to inherit a class' methods and have them access self member variables in python
I'm kind of new to Python, and I have been trying to figure out the best way to migrate a bunch of messy class methods (which access member variables) into a separate Utils.py type module t开发者_如何学运维o clean things up. The method names still need to be inherited by the base class, but they need to also have access to the parnet class methods. I'm detailing the background because I think there might be a better python way to solve this.
Basically I need to do something like the following, if I was trying to do this via inheritence: (I've played with super, but I haven't been able to solve it this way)
class Graph(GraphUtils):
graph_size = 10
def print_size(self):
print self.graph_size
class GraphUtils():
def set_size(self, new_size)
self.graph_size = new_size
if __name__ == "__main__":
g = Graph()
print "Graph default size: " + str(g.graph_size) # This is 10
g.set_size(20)
g.print_size() # I want it to print 20, but it'll print the default 10
I know there's another way to unify to import a class's methods and variables into another class, but I run the risk namespace collisions.
A technique I used in a similar case, where a separate module was needed to appear as an 'add-on' in our library looked as follows: (the 'add-on' idea came from the desire to optionally distribute additional functionality to the Graph class, it's all licensing related)
class Graph:
ext = None
graph_size = 10
def __init__(self):
self.ext = Extension()
self.ext._graph = self
def set_size(self, new_size):
self.graph_size = new_size
class Extension:
_graph = None
def process(self):
print "Processing graph size: " + str(self._graph.graph_size)
if __name__ == "__main__":
g = Graph()
print "Graph default size: " + str(g.graph_size) # This is 10
g.set_size(20)
g.ext.process()
# Output: Processing graph size: 20
Just wondering what you guys think is the best approach or if this can be reasonable (safely) accomplished in Python. (2.6+)
Thanks!
The solution to this is to define variables in the __init__() method of the class, and to make sure to initialize the inherited object.
__init__() is a 'magic' class method which is called when a new object is created from the class definition.
# Inherit object for new-style Python classes (recommended)
class GraphUtils(object):
# Override the __init__() magic-method.
def __init__(self):
# Initialize the inherited object by executing its __init__() method.
super(GraphUtils, self).__init__()
def set_size(self, new_size):
self.graph_size = new_size
# Inherit GraphUtils
class Graph(GraphUtils):
def __init__(self):
# Initialize the inherited GraphUtils object.
super(Graph, self).__init__()
# Declare the graph_size variable on creation of a new Graph object.
self.graph_size = 10
def print_size(self):
print self.graph_size
if __name__ == "__main__":
g = Graph()
# It is recommended to use str.format() instead of string concatonation
print "Graph default size: {}".format(g.graph_size) # will print "Graph default size: 10"
g.set_size(20)
g.print_size() # This will print 20
http://docs.python.org/reference/datamodel.html#basic-customization
http://docs.python.org/glossary.html#term-new-style-class
http://docs.python.org/library/functions.html#super
http://docs.python.org/library/string.html#string-formatting
精彩评论