Protected method in python

Pooya picture Pooya · Jul 14, 2012 · Viewed 44.5k times · Source

Possible Duplicate:
Making a method private in a python subclass
Private Variables and Methods in Python

How can I define a method in a python class that is protected and only subclasses can see it?

This is my code:

class BaseType(Model):
    def __init__(self):
        Model.__init__(self, self.__defaults())


    def __defaults(self):
        return {'name': {},
                'readonly': {},
                'constraints': {'value': UniqueMap()},
                'cType': {}
        }


    cType = property(lambda self: self.getAttribute("cType"), lambda self, data:              self.setAttribute('cType', data))
    name = property(lambda self: self.getAttribute("name"), lambda self, data: self.setAttribute('name', data))
    readonly = property(lambda self: self.getAttribute("readonly"),
                        lambda self, data: self.setAttribute('readonly', data))

    constraints = property(lambda self: self.getAttribute("constraints"))

    def getJsCode(self):
        pass

    def getCsCode(self):
        pass


    def generateCsCode(self, template=None, constraintMap=None, **kwargs):
        if not template:
            template = self.csTemplate

        if not constraintMap: constraintMap = {}
        atts = ""

        constraintMap.update(constraintMap)

        for element in self.getNoneEmptyAttributes():
            if not AbstractType.constraintMap.has_key(element[0].lower()):
                continue
            attTemplate = Template(AbstractType.constraintMap[element[0].lower()]['cs'])
            attValue = str(element[1]['value'])
            atts += "%s  " % attTemplate.substitute({'value': attValue})

        kwargs.update(dict(attributes=atts))

        return template.substitute(kwargs)



class  MainClass(BaseType, Model):
    def __init__(self):
        #Only Model will initialize
        Model.__init__(self, self.__defaults())
        BaseType.__init__(self)

    def __defaults(self):
        return {'name': {},
                'fields': {'value': UniqueMap()},
                'innerClass': {'value': UniqueMap()},
                'types': {}
        }

    fields = property(lambda self: self.getAttribute("fields"))
    innerClass = property(lambda self: self.getAttribute("innerClass"))
    types = property(lambda self: self.getAttribute("types"))


    @staticmethod
    def isType(iType):
    #        return type(widget) in WidgetSelector.widgets.itervalues()
        return isinstance(iType, AbstractType)

    def addType(self, type):
        if not MainClass.isType(type):
            raise Exception, "Unknown widget type %s" % type
        self.types[type.name] = type

I want that just subclasses of BaseType see the generateCsCode method of BaseType.

Answer

Ned Batchelder picture Ned Batchelder · Jul 14, 2012

Python does not support access protection as C++/Java/C# does. Everything is public. The motto is, "We're all adults here." Document your classes, and insist that your collaborators read and follow the documentation.

The culture in Python is that names starting with underscores mean, "don't use these unless you really know you should." You might choose to begin your "protected" methods with underscores. But keep in mind, this is just a convention, it doesn't change how the method can be accessed.

Names beginning with double underscores (__name) are mangled, so that inheritance hierarchies can be built without fear of name collisions. Some people use these for "private" methods, but again, it doesn't change how the method can be accessed.

The best strategy is to get used to a model where all the code in a single process has to be written to get along.