prevent / alter access to class variables [duplicate]

  • Last Update :
  • Techknowledgy :

The class of a class is called a metaclass. The default metaclass is type: the "type of types", or "class of classes". You want to make a subclass of type that doesn't allow its instances attributes to be set (exactly as you make a subclass of object that doesn't allow its instances attributes to be set when you're doing this at the instance level).

class CantTouchThis(type):
   def __setattr__(cls, attr, value):
   raise Exception("NO!")

class SomeClass(object):
   __metaclass__ = CantTouchThis

You're nearly there, you just need to move your __setattr__ method up to the metaclass:

class ReadOnlyClass(type):
def __setattr__(self, name, value):
raise ValueError(name)

class A(object, metaclass=ReadOnlyClass):
foo = "don't change me"

>>> a1 = A()
>>> a1.foo
"don't change me"
>>> A.foo
"don't change me"
>>> A.foo = 'bar'

Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
      A.foo = 'bar'
      File "<pyshell#4>", line 3, in __setattr__
         raise ValueError, name
         ValueError: foo
         >>> print A.foo
         don't change me
         >>> a2 = A()
         >>> a2.foo
         "don't change me"
         >>> a2.foo = 'x'
         >>> a2.foo
         'x'

Suggestion : 2

You can prevent duplicate values in a field in an Access table by creating a unique index. A unique index is an index that requires that each value of the indexed field is unique., Create a data-definition query that creates the unique index    You can do this by using SQL view. This method is not as easy as using Design view, but has an advantage: you can save the data-definition query and use it again later. This is useful if you periodically delete and re-create tables and want to use unique indexes on some of the fields., Create a data-definition query that creates the unique index    You can do this by using SQL view. This method is not as easy as using Design view, but has an advantage: you can save the data-definition query and use it again later. This is useful if you periodically delete and re-create tables and want to use unique indexes on some of the fields. ,Note: If duplicates already exist in the field for your table records, Access displays an error message (Error 3022) when you try and save the table changes with the new index. You'll need to remove those duplicate field values from the table records before you can set and save the new unique index.

CREATE UNIQUE INDEX index_name ON table(field);

Suggestion : 3

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 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.

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

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

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

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

Suggestion : 4

Last Updated : 25 Jun, 2022

Illustration:

final int THRESHOLD = 5;
// Final variable
final int THRESHOLD = 5;
// Final variable
final int THRESHOLD;
// Blank final variable
final int THRESHOLD;
// Blank final variable
static final double PI = 3.141592653589793;
// Final static variable PI

When a final variable is a reference to an object, then this final variable is called the reference final variable. For example, a final StringBuffer variable looks defined below as follows:

final StringBuffer sb;

Geeks
GeeksForGeeks

Geeks
GeeksForGeeks

20

1 2 3

Suggestion : 5

In fact, this doesn't prevent instance variables from accessing or modifying the instance. You can still perform the following operations: ,You can access the Student class's attributes and also modify their values, as shown below.,Above, we used std.name property to modify _name attribute. However, it is still accessible in Python. Hence, the responsible programmer would refrain from accessing and modifying instance variables prefixed with _ from outside its class. , Python doesn't have any mechanism that effectively restricts access to any instance variable or method. Python prescribes a convention of prefixing the name of the variable/method with a single or double underscore to emulate the behavior of protected and private access specifiers.

class Student:
   schoolName = 'XYZ School'
# class attribute

def __init__(self, name, age):
   self.name = name # instance attribute
self.age = age # instance attribute
>>> std = Student("Steve", 25) >>>
   std.schoolName 'XYZ School' >>>
   std.name 'Steve' >>>
   std.age = 20 >>>
   std.age
20
class Student:
   _schoolName = 'XYZ School'
# protected class attribute

def __init__(self, name, age):
   self._name = name # protected instance attribute
self._age = age # protected instance attribute
>>> std = Student("Swati", 25) >>>
   std._name 'Swati' >>>
   std._name = 'Dipa' >>>
   std._name 'Dipa'
class Student:
   def __init__(self, name):
   self._name = name
@property
def name(self):
   return self._name
@name.setter
def name(self, newname):
   self._name = newname
>>> std = Student("Swati") >>>
   std.name 'Swati' >>>
   std.name = 'Dipa' >>>
   std.name 'Dipa' >>>
   std._name # still accessible