Use class variables as instance vars?

2024/10/12 2:27:13

What I would like to do there is declaring class variables, but actually use them as vars of the instance. I have a class Field and a class Thing, like this:

class Field(object):def __set__(self, instance, value):for key, v in vars(instance.__class__).items():if v is self:instance.__dict__.update({key: value})def __get__(self, instance, owner):for key, v in vars(instance.__class__).items():if v is self:try:return instance.__dict__[key]except:return Noneclass Thing(object):foo = Field()

So when I instantiate a thing and set attribute foo, it will be added to the instance, not the class, the class variable is never actually re-set.

new = Thing()
new.foo = 'bar'
# (foo : 'bar') is stored in new.__dict__

This works so far, but the above code for Field is rather awkward. It has too look for the Field object instance in the classes props, otherwise there seems no way of knowing the name of the property (foo) in __set__ and __get__. Is there another, more straight forward way to accomplish this?

Answer

Every instance of Field (effectively) has a name. Its name is the attribute name (or key) which references it in Thing. Instead of having to look up the key dynamically, you could instantiate Fields with the name at the time the class attribute is set in Thing:

class Field(object):def __init__(self, name):self.name = namedef __set__(self, instance, value):instance.__dict__.update({self.name: value})def __get__(self, instance, owner):if instance is None:return selftry:return instance.__dict__[self.name]except KeyError:return Nonedef make_field(*args):def wrapper(cls):for arg in args:setattr(cls, arg, Field(arg))return clsreturn wrapper@make_field('foo')
class Thing(object):pass

And it can be used like this:

new = Thing()

Before new.foo is set, new.foo returns None:

print(new.foo)
# None

After new.foo is set, 'foo' is an instance attribute of new:

new.foo = 'bar'
print(new.__dict__)
# {'foo': 'bar'}

You can access the descriptor (the Field instance itself) with Thing.foo:

print(Thing.foo)
# <__main__.Field object at 0xb76cedec>

PS. I'm assuming you have a good reason why

class Thing(object):foo = None

does not suffice.

https://en.xdnf.cn/q/118246.html

Related Q&A

Get amount from django-paypal

I am using django-paypal to receive payment. I am currently paying as well as receiving payment using sandbox accounts. The payment procedure seems to be working fine. My problem is once I get back the…

Python get file regardless of upper or lower

Im trying to use this on my program to get an mp3 file regardless of case, and Ive this code:import glob import fnmatch, redef custom_song(name):for song in re.compile(fnmatch.translate(glob.glob("…

how to save h5py arrays with different sizes?

I am referring this question to this. I am making this new thread because I did not really understand the answer given there and hopefully there is someone who could explain it more to me. Basically my…

Cannot allocate memory on Popen commands

I have a VPS server with Ubuntu 11.10 64bit and sometimes when I execute a subprocess.Popen command I get am getting too much this error:OSError: [Errno 12] Cannot allocate memoryConfig details: For ea…

Python - find where the plot crosses the axhline on python plot

I am doing some analysis on some simple data, and I am trying to plot auto-correlation and partial auto-correlation. Using these plots, I am trying to find the P and Q value to plot in my ARIMA model.I…

remove tick labels in Python but keep gridlines

I have a Python script which is producing a plot consisting of 3 subplots all in 1 column.In the middle subplot, I currently have gridlines, but I want to remove the x axis tick labels.I have triedax2.…

Signal in PySide not emitted when called by a timer

I need to emit a signal periodically. A timer executes certain function, which emits the signal that I want. For some reason this function is not being emitted. I was able to reproduce the error on min…

pybuilder and pytest: cannot import source code when running tests

so i have a project:<root> |- src|-main|-python|-data_merger|- common|- constans|- controller|- resources|- rest|-tests|-unittest|-integrationtestdata_merger is marked as root (I am using Pycharm…

HTTPS proxy server python

I have a problem with my ssl server (in Python). I set the SSL proxy connection in my browser, and try to connect to my ssl server.This is the server:import BaseHTTPServer, SimpleHTTPServer import sslh…

Python 2.7.6 + unicode_literals - UnicodeDecodeError: ascii codec cant decode byte

Im trying to print the following unicode string but Im receiving a UnicodeDecodeError: ascii codec cant decode byte error. Can you please help form this query so it can print the unicode string properl…