Class constants with type of class - python-3.x

I do have a class with multiple methods in which I'd like to add constant values of instances of this class, to keep common used combinations handy.
class Text:
GREETING = Text('Hello')
LOREM = Text('Lorem ipsum dolor sit amen')
def __init__(self, text):
self.text = text
def double(self):
return f'{self.text}, {self.text}'
This doesn't work in that way (Undefined name 'Text'). I could declare the constants later on:
Text.GREETING = Text('Hello')
Text.LOREM = Text('Lorem ipsum dolor sit amen')
But that doesn't seem quite nice to me. I'd like to have it all inside of the class definition to be able to document everything nicely. Is there any other way possible?

You might make use of class- or static methods, if you don't mind the extra paranthesis and construction at call site:
class Text:
#staticmethod
def lorem():
return Text("Lorem ipsum")
# or
#classmethod
def greeting(cls):
return cls("Hello")

Does this look better to you?
class Text:
def __init__(self, text):
self.text = text
#classmethod
def register(cls, name, text):
setattr(cls, name, text)
Text.register('GREETING', 'hello')
Text.register('LOREM', 'Lorem ipsum dolor sit amen')
EDIT:
In case you need this pattern for multiple classes, it can be easily extracted to a separate class and use it as a Mixin:
class Registry:
#classmethod
def register(cls, name, text):
setattr(cls, name, text)
class Text(Registry):
def __init__(self, text):
self.text = text
Text.register('GREETING', 'hello')
Text.register('LOREM', 'Lorem ipsum dolor sit amen')

Related

With open inside of a class

Hello I am doing an assignment and I have a similar problem as to here but in this case I am unable to change the file = logsys(file_location) part due to the assignment rules. Is there any way I can do the "with" part inside of the class?
My code is shown below
doc = write("test_2.txt")
class HtmlTable:
def __init__(self, filename):
self.filename = filename
self.fp = None
def tag(self, text):
self.fp.write('<' + text+ '>' +'\n')
def __iadd__(self, text):
self.fp.write(text)
def __enter__(self):
self.fp = open(self.filename, "a+")
return self
def __exit__(self, exception_type, exception_value, traceback):
self.fp.close()
The idea is that i want to call the class and let it handle the with part for me

Layout placement probleme

I'm coding an CMQ application like in kivy. There is a probleme with my layout display : some multi-line buttons don't appear. I want that each line fit to the content.
It's my fist post, so please feel free to say if the way to ask question is wrong.
I have try with Grid, Box, StackLayouts with many .bind(minimum_height) and so on.
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.core.window import Window
questions = []
questions.append({'question' : 'Lorem ipsum dolor Lorem ipsum dolor sit amet sit amet',
'items':['Lorem', 'ipsum dolor nec sapien sit amet libero ', 'sit amet']})
questions.append({'question' : 'Curabitursit amet libero nec sapien nec .',
'items':['Lorem', 'ipsum dolor sapien nec libero',
'sit amet libero egestas dictum eu eget neque']})
questions.append({'question' : 'Curabitur nec sapien nec .',
'items':['Lorem', 'ipsum dolor sapien nec libero',
'sit amet libero egestas dictum eu eget neque']})
class MultiLineLabel(Button):
def __init__(self, **kwargs):
super(MultiLineLabel, self).__init__(**kwargs)
self.text_size = self.size
self.bind(size=self.on_size)
self.bind(text=self.on_text_changed)
self.size_hint_y = None # Not needed here
self.padding_y = 7
self.halign = 'center'
self.valign = 'middle'
# self.give_height = self.texture_size[1]
# print('init', self.give_height)
def on_size(self, widget, size):
self.text_size = size[0], None
self.texture_update()
# self.give_height = self.texture_size[1]
# print('dans l\'ombjet', self.texture_size[1])
if self.size_hint_y == None and self.size_hint_x != None:
self.height = max(self.texture_size[1], self.line_height)
elif self.size_hint_x == None and self.size_hint_y != None:
self.width = self.texture_size[0]
def on_text_changed(self, widget, text):
self.on_size(self, self.size)
class QuestionApplication(GridLayout):
def __init__(self, *args):
super(QuestionApplication, self).__init__(*args)
self.size_hint_y = None
self.cols = 2
self.spacing =10
for ask in questions:
label = Label(text=ask['question'],halign='center',
valign='top', size_hint=(0.6, None),
text_size=(self.width, None))
label.bind(size=label.setter('text_size'))
self.add_widget(label)
vbox = GridLayout(size_hint_y=None, cols=1,
size_hint_x=0.4)
for item in ask['items']:
button = MultiLineLabel(text=item)
vbox.add_widget(button)
self.add_widget(vbox)
self.bind(minimum_height=self.setter('height'))
class ExamApp(App):
def build(self):
return QuestionApplication()
if __name__ == '__main__':
Window.size = (500, 400)
ExamApp().run()
You are taking into account the sizes of your QuestionApplication children with the line:
self.bind(minimum_height=self.setter('height'))
but the vbox size is not accounting for changes in its children.
In your QuestionApplication __init__() method, you need to add
vbox.bind(minimum_height = vbox.setter('height'))
after you create the vbox.

how to set property for parent class inside child class in python?

I have two class one is Vehicle and one is BMW, I know I can create a color as property unver Vehicle. However how I set the property inside class BMW
but i am still able to access color as bmw.info,color? Can I do something like following?
class Vehicle:
def __init__(self, name):
self.name = name
self._color = None
#property
def color(self):
return self._color
#color.setter
def color(self, color):
self._color = color
class BMW:
def __init__(self, name):
self.info = Vehicle(name)
#can I do something like
class Vehicle:
def __init__(self, name):
self.name = name
class BMW:
def __init__(self, name):
self.info = Vehicle(name)
setattr(self.info, "color", None)
#info.property
def color(self):
return self._color
#info.color.setter
def color(self, color):
self._color = color
bmw = BMW('sister')
print(bmw.info.color)
bmw.info.color = 'red'
print(bmw.info.color)

How do i execute a method in a class from another method in a different class?

I would like a text to be updated when i press the search button. But I can't figure out how. Can someone explain what Im doing wrong on a kindergarden level?
Here is some code, I guess it explains what I like to do.
class One():
def setText(self, text):
self.text.config(state=NORMAL)
self.text.delete(1.0,END)
self.text.insert(END, text)
self.text.config(state=DISABLED)
def print(self):
self.setText('You are now searching.')
class PopUp():
def __init__(self, master):
self.searchButton = Button(command=self.onSearch, text ='search')
def onSearch(self):
mainClass = One()
mainClass.print()

change method resolution order

is it possible to change the method resolution order?
class A(object):
def __init__(self, a):
self.a=a
def method(self):
print('A method')
class B(object):
def __init__(self, b1, b2):
self.b1=b1
self.b2=b2
def method(self):
print('B method')
class C(A, B):
def __init__(self, name, **kwargs):
if name=='A':
A.__init__(self, a=kwargs['a'])
elif name=='B':
B.__init__(self, b1=kwargs['b1'], b2=kwargs['b2'])
I want change the MRO if the input name is 'B', so that when i call:
>>>c=C(name='B', b1=2, b2=3)
>>>c.method()
it returns 'B method'.
Thanks
Just change the definition of the C class to :
class C(B, A):
...
ie : change the order of the inherited classes.

Resources