473,655 Members | 3,063 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

decorator to prevent adding attributes to class?

After spending the morning debugging where I had misspelled the name of an
attribute (thus adding a new attr instead of updating an existing one), I
would like a way to decorate a class so that attributes cannot be (easily)
added.

I guess class decorators are not available yet (pep 3129), but probably
inheritance can be used.

Can anyone suggest an implementation?

Jul 11 '08 #1
5 4984
On Jul 11, 5:29*pm, Neal Becker <ndbeck...@gmai l.comwrote:
After spending the morning debugging where I had misspelled the name of an
attribute (thus adding a new attr instead of updating an existing one), I
would like a way to decorate a class so that attributes cannot be (easily)
added.

I guess class decorators are not available yet (pep 3129), but probably
inheritance can be used.

Can anyone suggest an implementation?
This article could give you same idea (it is doing the opposite,
warning you
if an attribute is overridden):
http://stacktrace.it/articoli/2008/0...-con-i-mixin1/

There is also a recipe that does exactly what you want by means of a
metaclass:
http://aspn.activestate.com/ASPN/Coo.../Recipe/252158
It is so short I can write it down here:
# requires Python 2.2+

def frozen(set):
"Raise an error when trying to set an undeclared name."
def set_attr(self,n ame,value):
if hasattr(self,na me):
set(self,name,v alue)
else:
raise AttributeError( "You cannot add attributes to %s" %
self)
return set_attr

class Frozen(object):
"""Subclass es of Frozen are frozen, i.e. it is impossibile to add
new attributes to them and their instances."""
__setattr__=fro zen(object.__se tattr__)
class __metaclass__(t ype):
__setattr__=fro zen(type.__seta ttr__)

Of course using frozen classes is not Pythonic at all, and I wrote the
recipe as
a proof of concept, not to use it.

Michele Simionato
Jul 11 '08 #2
Michele Simionato wrote:
This article could give you same idea (it is doing the opposite,
warning you
if an attribute is overridden):
http://stacktrace.it/articoli/2008/0...-con-i-mixin1/

There is also a recipe that does exactly what you want by means of a
metaclass:
http://aspn.activestate.com/ASPN/Coo.../Recipe/252158
It is so short I can write it down here:
# requires Python 2.2+

def frozen(set):
"Raise an error when trying to set an undeclared name."
def set_attr(self,n ame,value):
if hasattr(self,na me):
set(self,name,v alue)
else:
raise AttributeError( "You cannot add attributes to %s" %
self)
return set_attr

class Frozen(object):
"""Subclass es of Frozen are frozen, i.e. it is impossibile to add
new attributes to them and their instances."""
__setattr__=fro zen(object.__se tattr__)
class __metaclass__(t ype):
__setattr__=fro zen(type.__seta ttr__)
I don't get it. Why use a metaclass? Wouldn't the following be the same,
but easier to grasp:

class Frozen(object):
def __setattr__(sel f, name, value):
if not hasattr(self, name):
raise AttributeError, "cannot add attributes to %s" % self
object.__setatt r__(self, name, value)

Btw, the main drawback with Frozen is that it will not allow to set any
new attributes even inside __init__.
Some people would advise to use __slots__:
http://docs.python.org/ref/slots.html#l2h-222
Some other people would advise NOT to use __slots__:
http://groups.google.com/group/comp....2e859b9c002b28

Personally, if I must absolutely, I'd go for explicitely freeze the
object at the end of __init__:

class Freezeable(obje ct):
def freeze(self):
self._frozen = None

def __setattr__(sel f, name, value):
if hasattr(self, '_frozen') and not hasattr(self, name):
raise AttributeError
object.__setatt r__(self, name, value)
class Foo(Freezeable) :
def __init__(self):
self.bar = 42
self.freeze() # ok, we set all variables, no more from here
x = Foo()
print x.bar
x.bar = -42
print x.bar
x.baz = "OMG! A typo!"
Cheers,
RB
Jul 11 '08 #3
On Jul 11, 6:38*pm, Robert Bossy
I don't get it. Why use a metaclass? Wouldn't the following be the same,
but easier to grasp:

class Frozen(object):
* * def __setattr__(sel f, name, value):
* * * *if not hasattr(self, name):
* * * * * raise AttributeError, "cannot add attributes to %s" %self
* * * *object.__setat tr__(self, name, value)
This is easier, but it does not stop the user from
adding class level attributes: this is the job
of the metaclass. If you don't care about
class level attributes (including methods,
properties, etc) and you are content with restricting
only the instance attributes your recipe is fine, yes.
Jul 11 '08 #4
Robert Bossy wrote:
class Foo(Freezeable) :
def __init__(self):
self.bar = 42
self.freeze() # ok, we set all variables, no more from here
x = Foo()
print x.bar
x.bar = -42
print x.bar
x.baz = "OMG! A typo!"
Pretty nice, but unfortunately the subclass has to remember to call freeze
in it's init. Too bad that can't be automated.
Jul 11 '08 #5
On Jul 11, 9:24*pm, Neal Becker <ndbeck...@gmai l.comwrote:
Robert Bossy wrote:
class Foo(Freezeable) :
def __init__(self):
self.bar = 42
self.freeze() # ok, we set all variables, no more from here
x = Foo()
print x.bar
x.bar = -42
print x.bar
x.baz = "OMG! A typo!"

Pretty nice, but unfortunately the subclass has to remember to call freeze
in it's init. *Too bad that can't be automated.
It can with a metaclass redefining the __call__ method
to call freeze after instantation. But there
would a lot of magic going on such a design.
Jul 12 '08 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
2298
by: Sandy Norton | last post by:
If we are going to be stuck with @decorators for 2.4, then how about using blocks and indentation to elminate repetition and increase readability: Example 1 --------- class Klass: def __init__(self, name):
37
2594
by: Bengt Richter | last post by:
ISTM that @limited_expression_producing_function @another def func(): pass is syntactic sugar for creating a hidden list of functions. (Using '|' in place of '@' doesn't change the picture much (except for people whose tools depend on '@' ;-)). I.e., (not having the source or time to delve) the apparent semantics of the above is something roughly like
5
1808
by: Doug | last post by:
I am looking at using the decorator pattern to create a rudimentary stored proc generator but am unsure about something. For each class that identifies a part of the stored proc, what if I want to add a value dynamically. I'm including some code to show what I mean. This is real basic on what I want to do: using System; namespace ClassLibrary1 {
1
1530
by: Doug | last post by:
I am looking at using the decorator pattern to create a rudimentary stored proc generator but am unsure about something. For each class that identifies a part of the stored proc, what if I want to add a value dynamically. I'm including some code to show what I mean. This is real basic on what I want to do: using System; namespace ClassLibrary1 {
4
1609
by: Wilbert Berendsen | last post by:
Hi, is it possible to manipulate class attributes from within a decorator while the class is being defined? I want to register methods with some additional values in a class attribute. But I can't get a decorator to change a class attribute while the class is still being defined. Something like: class Parser(object): regexps =
0
899
by: Christian Heimes | last post by:
Wilbert Berendsen schrieb: It's really tricky . The class object doesn't exists yet. It's created after all functions are parsed and created. You have can walk up the stack frames but it's ugly. Christian
0
831
by: rbossy | last post by:
>class Foo(Freezeable): Not to mention that subclasses constructors could be bit, like that: class Foo(Freezeable): ... class Bar(Foo): def __init__(self, *args, **kw): Foo.__init__(self, *args, **kw)
14
4339
by: Rafe | last post by:
Hi, I've encountered a problem which is making debugging less obvious than it should be. The @property decorator doesn't always raise exceptions. It seems like it is bound to the class but ignored when called. I can see the attribute using dir(self.__class__) on an instance, but when called, python enters __getattr__. If I correct the bug, the attribute calls work as expected and do not call __getattr__. I can't seem to make a simple...
8
2733
by: Bryan | last post by:
I want my business objects to be able to do this: class Person(base): def __init__(self): self.name = None @base.validator def validate_name(self): if not self.name: return
0
8380
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8296
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8710
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8497
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
4150
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4299
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2721
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1928
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1598
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.