45

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.

11
  • @jamylak No No no no no I just want to say how to define a method protected, I know about underscore Commented Jul 14, 2012 at 11:44
  • Why minus??? why? it is my problem and I searched a lot and I did not find anything Commented Jul 14, 2012 at 11:46
  • 1
    @Pooya: you have your answer: You don't do this in Python. Describe the larger problem, and we can help you find a Python-appropriate solution. Commented Jul 14, 2012 at 11:47
  • 2
    @Pooya, ok, you can't do it. Write the docs explaining what developers should call and what they should not. That's the Python way. Commented Jul 14, 2012 at 12:04
  • 3
    If your developers don't read docs, you have a bigger problem. Fix that first. Yes, I know it is difficult, but a compiler can't improve your team. Commented Jul 14, 2012 at 12:16

2 Answers 2

108

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.

Sign up to request clarification or add additional context in comments.

4 Comments

yes I know about _ and __ but I want to know about how to make my method protected, exactly like protected in java
The answer is very simple, and has been provided: You can't in Python.
@NedBatchelder "We are adults!" I wish you could say that to vandals and hackers :(
I hope the "vandals and hackers" comment isn't related to protected methods. If a hacker is running their code in your process, no amount of protected methods is going to save you.
13

You can't. Python intentionally does not support access control. By convention, methods starting with an underscore are private, and you should clearly state in the documentation who is supposed to use the method.

4 Comments

By convention, one underscore is considered protected and two underscores are considered private.
@l__flex__l: Double leading underscores for instance attributes invokes name mangling with very specific semantics. It's not a convention, it's part of the language defintion. According to PEP 8, one leading underscore is a "weak internal use indicator". I don't think there is any useful analogy to the C++ "protected" and "private" access modificators.
In the PEP 8 check out the section "Designing for inheritance". Particularly the paragraph that starts with "Another category of attributes are those that are part of the "subclass API" (often called "protected" in other languages)". To me, that section describes protected attributes. Also many others believe so like this guy. I know articles on the internet is never a proof. But, enough people agree on this so that by definition is a convention, no?
@l__flex__l: Fair enough. :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.