How can I prevent or alter access to class variables in Python?

0 votes

Is there a way to prevent or alter access to class variables in Python as one can via overriding __setattr__ for instance variables?

Note that this question is mistitled and actually refers to instance variables, not class variables.

Based on reading multiple posts about the (apparent) deathtrap that is __slots__, I'd prefer not to go that route (and I haven't looked into it enough to know if it does what I'm asking).

Example:

class A(object):

    foo = "don't change me"

    def __setattr__(self, name, value):
        raise ValueError

if __name__ == '__main__':
a1 = A()
print a1.foo # don't change me
print A.foo  # don't change me

A.foo = 'bar' # ideally throw an exception or something here
print A.foo   # bar
a2 = A()
print a1.foo  # bar
print a2.foo  # bar
Dec 5, 2018 in Python by charlie_brown
• 7,720 points
63 views

1 answer to this question.

0 votes

The ActiveState solution that Pynt references makes instances of ROClass have read-only attributes. Your question seems to ask if the class itself can have read-only attributes.

Here is one way, based on Raymond Hettinger's comment:

#!/usr/bin/env python
def readonly(value):
    return property(lambda self: value)

class ROType(type):
    CLASS_PROPERTY = readonly(1)

class Foo(object):
    __metaclass__=ROType

print(Foo.CLASS_PROPERTY)
# 1

Foo.CLASS_PROPERTY=2
# AttributeError: can't set attribute

The idea is this: Consider first Raymond Hettinger's solution:

class Bar(object):
    CLASS_PROPERTY = property(lambda self: 1)
bar=Bar()
bar.CLASS_PROPERTY=2

It shows a relatively simple way to give bar a read-only property.

Notice that you have to add the CLASS_PROPERTY = property(lambda self: 1) line to the definition of the class of bar, not to bar itself.

So, if you want the class Foo to have a read-only property, then the parent class of Foo has to have CLASS_PROPERTY = property(lambda self: 1) defined.

The parent class of a class is a metaclass. Hence we define ROType as the metaclass:

class ROType(type):
    CLASS_PROPERTY = readonly(1)

Then we make Foo's parent class be ROType:

class Foo(object):
    __metaclass__=ROType
answered Dec 5, 2018 by ariaholic
• 7,340 points

Related Questions In Python

+2 votes
6 answers

How can I change directory or "cd" in Python?

Context Manager: cd import os class cd:     """Context manager for ...READ MORE

answered Oct 18, 2018 in Python by Nabarupa
121 views
0 votes
1 answer

How do I use urllib to see if a website is 404 or 200 in Python?

For Python 3, try doing this: import urllib.request, ...READ MORE

answered Nov 29, 2018 in Python by Nymeria
• 3,520 points

edited Dec 11, 2018 by Nymeria 821 views
0 votes
1 answer

How can I change the data type to string in Python?

You can use str(variablename) This is called conversion ...READ MORE

answered Dec 17, 2018 in Python by Shuvodip
49 views
0 votes
1 answer

I have a dictonary in python how to access the value field?

dic={"car":["limo","sedan"]} print (dic.keys())    <-----------------------Fetch the key "car" print (dic['car'][0])   <------------------------Fetch ...READ MORE

answered Dec 19, 2018 in Python by Shuvodip
79 views
+1 vote
2 answers

how can i count the items in a list?

Syntax :            list. count(value) Code: colors = ['red', 'green', ...READ MORE

answered Jul 6 in Python by Neha
• 330 points

edited Jul 8 by Kalgi 282 views
+4 votes
6 answers
0 votes
1 answer

How can I expose callbacks to Fortran using Python

The code that I've written below. The ...READ MORE

answered Aug 23, 2018 in Python by ariaholic
• 7,340 points
145 views
0 votes
1 answer

How does Python know whether a variable in the class is a method or a variable?

In python objects/variables are wrapped into methods ...READ MORE

answered Sep 18, 2018 in Python by ariaholic
• 7,340 points
51 views