MetaFoo | A metaprogramming library for .NET | Database library
kandi X-RAY | MetaFoo Summary
kandi X-RAY | MetaFoo Summary
A metaprogramming library for .NET.
Support
Quality
Security
License
Reuse
Top functions reviewed by kandi - BETA
Currently covering the most popular Java, JavaScript and Python libraries. See a Sample of MetaFoo
MetaFoo Key Features
MetaFoo Examples and Code Snippets
Community Discussions
Trending Discussions on MetaFoo
QUESTION
I'm trying to create a class with a base attribute shared by all instances that is used as a template when initialising an instance attribute. Ideally, it would be final/immutable but this is Python so I'm just not going to overwrite it.
...ANSWER
Answered 2021-Apr-23 at 13:53I wonder why do you think that if you had not got the most basic of attributes in classes and instances, you'd succeed in writing metaclasses.
In fact, what you described as your need, is the basic behavior of objects in Python: your attribute is computed when the class body is executed (usually at module import time), once, and is available in all instances.
Moreover, if there was code in one instance doing something like: self.class_template_attr = "new value"
, that would create a new attribute in that instance only, which would shadow the class attribute - but just for that instance. The original value would remain the default visible value for all other instances.
Now, about your metaclass: ou try to create a property on the metaclass itself and have it cascading down to the classes - that would certainly be overkill by a long shot.
There are some problems with your implementation as well - but starting with a non-error: while a "@property" would work on a metaclass and be available as a property on the class object, that would work, but you won't find an example for this in any docs: due to the fact they are not meant to be used in this way. They work because Python is extremely consistent in its rules, and then, classes, being objects and instances of the metaclass, are no exception to the descriptor protocol which is "what makes property
work": a descriptor on the metaclass will be used for attribute retrieval on the class. However, the same descriptor on the metaclass will not be used to retrieve the attribute from the instance of that class.
There are a few other problems on the implementation, but the overwhelming redundancy is the the worst part. I'd add a side note not to rely on the double underscore prefix for "private" attributes too much. It can be useful on occasion, but it certainly is much less so than on languages with proper public
, private
and protected
modifiers - they are more of use to prevent name clashes in a complicated class hierarchy using multiple inheritance and mixins, and will just get in your way sooner or later if used otherwise.
On making myinstance.myattr
:
- Python will first check if the attribute exists in the clas of myinstance and, if so, if it is a descriptor (the class for the attribute value should have the
__get__
method.property
implements that). If yes, that is called, and the resulting value is returned; - Python will check for the attribute on the instance itself. Ordinarily, as an entry on the instance's
__dict__
. If so, that value is returned. - Python looks for the attribute in the instance's class, regardless of it being a descriptor.
- If not found, it will check if the class has a
__getattr__
method - that will be called with the intended attribute name, and either return a value or raise AttributeError. - If nothing is found this far, the search fails, and AttributeError is raised.
Note that for steps (1), (3) and (4) above, the class is searched, but not its own metaclass - instead, the search follows through the inheritance chain: in each of these steps the superclasses (in the order they show in myinstance.__class__.__mro__
) are searched for the attribute.
property
for a read-only class attribute
If setting a plain class attribute is not enough, and you'd like to prevent instances from accidentally overwriting the instance value with self.myattr = "foo"
, a readonly property can be created on the class body. No need to resort to metaclasses.
Note that this still won't prevent the attribute from being overwritten in the class itself (with self.__class__.myattr = "new value"
- if ou want to prevent that, then you'd need a metaclass and customize its __setattr__
method. That is the Pythonic concept of "consenting adults": if one writes all the way self.__class__.myattr = "new value"
, they are very concerned to change the attribute, regardless of the intent of the class author, and willing to assume responsibility for that).
Anyway, for instance imutable attributes, and, as an extra, you get your expensive value lazily computed: it will be computed at the first occasion it will be actually needed, not at module import time: there is a trade off: you gain agility at app startup and pay the cost for that computation when it is actually first used:
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install MetaFoo
Support
Reuse Trending Solutions
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesStay Updated
Subscribe to our newsletter for trending solutions and developer bootcamps
Share this Page