Posts: 3
Threads: 1
Joined: Apr 2025
Hello,
I am pretty new to python and OOP, so please don't be too harsh on my question
I have the following code:
class frame:
def __init__(self, width, height):
self.frame_width = width
self.frame_height = height
def image(self):
self.width = 0.8 * self.frame_width
self.height = 0.8 * self.frame_height
picture = frame(60,40) My question is, how can I access the image width in the following manner:
picture.image.width
Posts: 8,158
Threads: 160
Joined: Sep 2016
I will start with more general remarks. It is convention that class name should start with capital letter, so better use Frame , not frame . Then it looks like you actually want image to be a class on its own (i.e. the image inside the frame), right? At the moment it's a method of class Frame . If it would not be a class on its own, then width and height would be properties of the frame And probably you want them to be fixed as proportion to frame size, so use @property decorator
class Frame:
def __init__(self, width, height):
self.frame_width = width
self.frame_height = height
@property
def image_width(self):
return 0.8 * self.frame_width
@property
def image_height(self):
return 0.8 * self.frame_height
picture = Frame(100, 200)
print(f'Frame: {picture.frame_width}X{picture.frame_height}, picture:{picture.image_width}X{picture.image_height}')
Posts: 3
Threads: 1
Joined: Apr 2025
Apr-11-2025, 05:39 PM
(This post was last modified: Apr-11-2025, 05:39 PM by Abedin.)
(Apr-11-2025, 07:29 AM)buran Wrote: I will start with more general remarks. It is convention that class name should start with capital letter, so better use Frame , not frame . Then it looks like you actually want image to be a class on its own (i.e. the image inside the frame), right? At the moment it's a method of class Frame . If it would not be a class on its own, then width and height would be properties of the frame And probably you want them to be fixed as proportion to frame size, so use @property decorator
class Frame:
def __init__(self, width, height):
self.frame_width = width
self.frame_height = height
@property
def image_width(self):
return 0.8 * self.frame_width
@property
def image_height(self):
return 0.8 * self.frame_height
picture = Frame(100, 200)
print(f'Frame: {picture.frame_width}X{picture.frame_height}, picture:{picture.image_width}X{picture.image_height}')
Thank you so much for your reply and solution! I think I figured out how to achieve what I was originally going for. If you want to have an image with a property 'width' and then a frame with the same property, you need to have two different classes with the same property. If your image size depends somehow on the frame size, and you want to have a property image in your frame class, one can initialize the image class within the frame class as follows:
class frame:
def __init__(self, width, height):
p = 0.8
self.width = width
self.height = height
self.image = image(self.width, self.height, p)
class image:
def __init__(self, width, height, p):
self.width = p * width
self.height = p * height
picture = frame(60,40)
print(picture.image.width)
48.0
print(picture.width)
60
Posts: 6,783
Threads: 20
Joined: Feb 2020
I think it makes a lot more sense to do this:
class Frame:
def __init__(self, width, height):
p = 0.8
self.width = width
self.height = height
self.image = Image(self.width * p, self.height * p)
class Image:
def __init__(self, width, height):
self.width = width
self.height = height Having width as an argument to Image.__init__ and as an attribute, it is weird that the two values would not match immediately after an instance is created.
Now is a good time to start following python coding conventions. Class names start with an uppercase letter. This makes it easy to tell the difference between creatin an instance of a class and calling a function.
p is an odd thing. There are multiple ways that p can be handled. You could make p a class attribute.
class ImageFrame:
PROPORTIONALITY = 0.8
def __init__(self, width, height):
self.width = width
self.height = height
self.image = Image(self.width * self.PROPORTIONALITY, self.height * self.PROPORTIONALITY) An advantage with this is code can ask the ImageFrame (a better name than Frame for a Frame that's defining attribute is it contains an image) what is the value of the proportionality constant. It also makes the proportionality constant stand out. If you later decide that the images should be 90% as big as the frame, it is easy to find where proportionality is set.
You could make p an argument in the init method. If you want p to be 0.8 most of the time, you can set a default value.
class ImageFrame:
def __init__(self, width, height, proportionality=0.8):
self.width = width
self.height = height
self.image = Image(self.width * proportionality, self.height *proportionality) An advantage to this approach is you can make different image frames with different p values.
Posts: 3
Threads: 1
Joined: Apr 2025
Apr-12-2025, 12:59 AM
(This post was last modified: Apr-12-2025, 01:01 AM by Abedin.)
(Apr-11-2025, 07:41 PM)deanhystad Wrote: I think it makes a lot more sense to do this:
class Frame:
def __init__(self, width, height):
p = 0.8
self.width = width
self.height = height
self.image = Image(self.width * p, self.height * p)
class Image:
def __init__(self, width, height):
self.width = width
self.height = height Having width as an argument to Image.__init__ and as an attribute, it is weird that the two values would not match immediately after an instance is created.
Now is a good time to start following python coding conventions. Class names start with an uppercase letter. This makes it easy to tell the difference between creatin an instance of a class and calling a function.
p is an odd thing. There are multiple ways that p can be handled. You could make p a class attribute.
class ImageFrame:
PROPORTIONALITY = 0.8
def __init__(self, width, height):
self.width = width
self.height = height
self.image = Image(self.width * self.PROPORTIONALITY, self.height * self.PROPORTIONALITY) An advantage with this is code can ask the ImageFrame (a better name than Frame for a Frame that's defining attribute is it contains an image) what is the value of the proportionality constant. It also makes the proportionality constant stand out. If you later decide that the images should be 90% as big as the frame, it is easy to find where proportionality is set.
You could make p an argument in the init method. If you want p to be 0.8 most of the time, you can set a default value.
class ImageFrame:
def __init__(self, width, height, proportionality=0.8):
self.width = width
self.height = height
self.image = Image(self.width * proportionality, self.height *proportionality) An advantage to this approach is you can make different image frames with different p values.
Thank you for your help. I appreciate that. I like the solution and this was what I was looking for. I will implement that into my code.
Posts: 1,093
Threads: 143
Joined: Jul 2017
If you return something from image() then you have it.
class Frame:
def __init__(self, width, height, factor):
self.frame_width = width
self.frame_height = height
self.factor = factor
def image(self):
return (self.frame_width * self.factor, self.frame_height * self.factor)
Picture = Frame(60,40,0.8)
tup = Picture.image() # returns (48.0, 32.0)
Posts: 8,158
Threads: 160
Joined: Sep 2016
(Apr-12-2025, 12:59 AM)Abedin Wrote: I like the solution and this was what I was looking for. I will implement that into my code. Just keep in mind, that Image.width and Image.height can be manipulated separately and thus can break the proportionality factor you set for Frame
|