Can An Attribute Access Another Attribute?
Solution 1:
OP asked: 1: Am I setting and implementing the problem correctly? I would like to offer an alternative ( less redundant) for your class implementation by using inheritance. The code below is written in Python 2.7.3
classMetadata(object):
def__init__(self, meta_file_path):
self.Path= meta_file_path
defReadBandPath(self,band_number):
print'ReadBandPath: ', str(band_number)
defReadLocation(self):
print'ReadLocation'defReadCameraInfo(self):
print'ReadCameraInfo'defGetSomeOtherInfo(self):
print'GetSomeOtherInfo'classBand(Metadata):
def__init__(self, file_path, band_number):
Metadata.__init__(self, file_path )
self.number= band_number
self.Path= self.ReadBandPath(self.number)
defDoSomething(self):
self.GetSomeOtherInfo()
classImage(Band):
def__init__(self, file_path, band_number, destfile):
Band.__init__(self, file_path, band_number)
self.pngfile= destfile
defSaveAsPng(self):
print'Saved as png : ', self.pngfile
# Now you can create instances of Image like this:
Band1= Image('samplepath1',1,'file4.png')
Band2= Image('samplepath2',2,'filex.png')
Band3= Image('samplepath3',3,'afile.png')
# Methods and attributes from Metadata , Band and Image :
Band3.SaveAsPng()
Band2.DoSomething()
Band1.ReadCameraInfo()
print'Band1: ',Band1.number
print'Band2: ',Band2.number
print'Band3: ',Band3.number
# etc...
Solution 2:
It looks like if I update some info in Image.Meta after creating Image.BandN, then Image.BandN.Meta won't be simultaneously updated, right?
No, this isn't a problem; my_image.Band1.Meta
will be a reference to the same object as my_image.Meta
.
It's only if you reassign my_mage.Meta
to name a different object (as opposed to mutating the object it names) that you'll have a problem.
But you can test this yourself, by printing out id(my_image.Meta)
and id(my_image.Band1.Meta)
, or checking my_image.Meta is my_image.Band1.Meta
.
My way seems a little redundant to me, and more importantly it seems "static".
Well, it is a bit redundant and static in that it handles exactly three bands, and would need changes all over the place if you wanted to use the same code for, say, CMYK. If that's something you might ever want to do, you might want to consider:
self.Bands = []
self.Bands.append(Band(self.Meta, 1))
self.Bands.append(Band(self.Meta, 2))
self.Bands.append(Band(self.Meta, 3))
Or:
self.Bands = [Band(self.Meta, i) for i inrange(3)]
Alternatively, if RGB is an inherent and unchangeable part, you may want to use names instead of numbers (just 'R'
', 'G'
, 'B'
). And then, you might still want to put them into a collection instead of separate variables:
self.Bands = {name: Band(self.Meta, name) fornamein ('R', 'G', 'B')}
Solution 3:
It looks like if I update some info in Image.Meta after creating Image.BandN, then Image.BandN.Meta won't be simultaneously updated, right?
This depends on how you do the updating. After creating your Image
instance (which I will call img
), img.Meta
and img.BandN.Meta
are the same object.
If you assign a new value to img.Meta
then img.BandN.Meta
will not be updated, since img.Meta
is now a new object and img.BandN.Meta
is still the original.
However if you modify img.Meta
, for example img.Meta.some_attribute = new_value
, then img.BandN.Meta
will also be updated since they are still the same object.
Your code looks fine the way it is as long as you are modifying img.Meta
instead of giving it a new value.
Solution 4:
That all seems reasonable.
Any method of Band
, if it needs to consult the metadata, can do so via the self.Meta
reference.
As an aside, consider adopting the naming convention from the Python Style Guide, i.e., reserve CapitalizedWords for class names only; use lower_case_with_underscores for parameters, attributes, methods, and variables. (The Metadata
parameter to Band.__init__
is shadowing the Metadata
class.)
Solution 5:
You've dissected the image into three classes, but Band and MetaData are tightly coupled, and Image doesn't do much. Possibly Band is more simply represented as an array of ints or floats.
Rather than try to design an object and class hierarchy, I'd start with the simplest implementation possible. If the class gets too big or the code becomes unwieldy, then you can start separating classes out. You'll find that simple, flat code is easier to reshape than highly crafted object hierarchies once you get to the point of needing to clean it up.
classImage(object):def__init__(self, meta_file_path):
self.meta_file_path = meta_file_path
self.bands = {}
for b in'RGB':
self.bands[b] = self.load_band(b)
defread_location(self):
...
defprocess_band(self, b):
...
Post a Comment for "Can An Attribute Access Another Attribute?"