3

I'd like to be able to extend a class without inheriting one of the class variables.

Given this scenario:

class A:
    aliases=['a','ay']

class B(A):
    pass

print(B.aliases)

I would rather get an error that B has not defined the aliases variable rather than have B accidentally called ay.

One could imagine a solution where aliases becomes a member of the instantiated object (self.aliases) and is set in __init__ but I really want to be able to access the aliases using the cls object rather than an instance of the class.

Any suggestions?

6
  • see this answer: stackoverflow.com/questions/1641219/… Commented Sep 6, 2019 at 14:31
  • Yes. I read that already. It did not answer this question. Commented Sep 6, 2019 at 14:32
  • Python just doesn't have the types of visibility restrictions that other languages do. (Also, what you do mean by "rather than have B accidentally called ay"?) Commented Sep 6, 2019 at 14:40
  • Since "ay" is an alias to A but would also be used for B in the above. Commented Sep 6, 2019 at 14:48
  • 1
    What's wrong with putting aliases = [] in B? Commented Sep 6, 2019 at 14:50

2 Answers 2

5

Python does not have REALY private attributes. But you can define it with a double underscore (__):

class A:
    __aliases=['a','ay']

class B(A):
    pass

print(B.__aliases) # yields AttributeError

But you still will be able to access it with:

print(B._A__aliases)
Sign up to request clarification or add additional context in comments.

3 Comments

Oh. This is just what I was hoping for.
And that is the solution!
I didn't realize the "__" mangling worked for class variables.
2

This is kindof a ganky work around but here you go:

class K:
    def __init__(self):
        self.mems = dir(self)

def defaultMembers():
    k = K()
    return(k.mems)

class A:
    aliases=['a','ay']

class B(A):
    def __init__(self):
        for k in set(dir(self))-set(defaultMembers()):
            print("removing "+k)
            setattr(self, k, None)

a = A()
b = B()
print(b.aliases)
#None
print(a.aliases)
#['a','ay']

I guess all you really need is the setattr(self, "aliases", None) still this results in a None and not a non-variable. Unfortunately calsses don't support deletion because I tried to use del first.

4 Comments

I think the point was to modify the behaviour when accessing aliases from the class object (B) not a class instance (b).
idk how he expects to work with class variables without instantiating them
I was hoping there was some simple workaround such as "__aliases" not getting copied on extension.
I'm thinking this answer should now be removed. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.