Is there another way to do a bunch of methods calls ? - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Is there another way to do a bunch of methods calls ? (/thread-7279.html) |
Is there another way to do a bunch of methods calls ? - Windspar - Jan-02-2018 class Test: def __init__(self): self.a = 1 def one(self): self.a += 1 return self def two(self): self.a += 2 return self def three(self): self.a += 3 return self test = Test() \ .one() \ .two() \ .three() print(test.a) RE: Is there another way to do a bunch of methods calls ? - mpd - Jan-02-2018 test.one() test.two() test.three() # or ... for f in [test.one, test.two, test.three]: f()What exactly are you looking for? RE: Is there another way to do a bunch of methods calls ? - Windspar - Jan-02-2018 I'm looking for another style with less typing. This looks nicer. Just wondering if python has another way ? test = (Test() .one() .two() .three()) RE: Is there another way to do a bunch of methods calls ? - buran - Jan-02-2018 this is ugly and non-pythonic please, don't do it RE: Is there another way to do a bunch of methods calls ? - Windspar - Jan-02-2018 I'm looking for ways to set items up in my classes. Right now looking at dict for args and kwargs. import pygame from pyscene.objects import PySceneObject from pyscene.tool import gradient, twist # Text are static. Can be transform in Text Click. # Text can have a hilight color. # Text can have colorful text class TextInfo: def __init__(self, color, alpha): self.alpha = alpha self.image = None self.r_image = None self.color = twist.colorx(color) def set_color(self, color): self.color = twist.colorx(color) # color takes pygame.Color args or pygame.Surface class Text(PySceneObject): keys = ['text', 'pos', 'font', 'color', 'alha', 'group', 'callback', 'allow_bindings', 'hilight', 'toggle', 'blink', 'angle'] default = { 'text':'Text', 'pos':(0,0), 'font':None, 'color':'white', 'alha':None, 'group':None, 'callback':None, # (callback, pydata=None) 'allow_bindings':True, 'hilight':None, # (color, alpha=None) 'toggle':None, # (color, alpha=None) 'blink':None, # (color, time_interval, interval, alpha=None) 'angle':None } def __init__(self, parent, text, x, y, font=None, color='white', group=None, callback=None, pydata=None, alpha=None, allow_bindings=True): PySceneObject.__init__(self, parent, (x, y), 'Text', group, allow_bindings) if font is None: self._font = pygame.font.Font(None, 24) else: self._font = font self._info = {'base': TextInfo(color, alpha)} self._text = text self._angle = None self._r_rect = None self._render(self._info['base']) self.callback = callback self.pydata = pydata if allow_bindings: parent.bind_blit(self._key + 'blit__', self.blit) def set_callback(self, callback, pydata=None): self.callback = callback self.pydata = pydata return self def event_mousemotion(self, event, key, pydata): if event is None: self._hover = False if self._info.get('blink', False): if self._parent.timer[self._key + 'timer__'].stop: self._parent.timer.start(self._key + 'timer__') elif self.enable: self._hover = self._rect.collidepoint(event.pos) if self._info.get('hover', False) and self._hover: if self._info.get('blink', False): self._parent.timer.stop(self._key + 'timer__') else: if self._info.get('blink', False): if self._parent.timer[self._key + 'timer__'].stop: self._parent.timer.start(self._key + 'timer__') def event_mousebuttondown(self, event, key, pydata): PySceneObject.event_mousebuttondown(self, event, key, pydata) if event.button == 1: if self.callback and self._hover: self.callback(self, self.pydata) def set_hilight(self, color, alpha=None): if self._info.get('hover', False): self._info['hover'].set_color(color) self._info['hover'].alpha = alpha else: self._info['hover'] = TextInfo(color, alpha) self._render(self._info['hover']) return self def set_toggle(self, color, alpha=None): if self._group is None: self.allow_toggle = True if self._info.get('toggle', False): self._info['toggle'].set_color(color) self._info['toggle'].alpha = alpha else: self._info['toggle'] = TextInfo(color, alpha) self._render(self._info['toggle']) return self def set_blink(self, color, time_interval, interval, alpha=None): if self._info.get('blink', False): self._info['blink'].set_color(color) self._info['blink'].alpha = alpha else: self._info['blink'] = TextInfo(color, alpha) self._info['blink'].interval = interval self._info['blink'].time_interval = time_interval self._info['blink'].blink = False self._parent.timer.add(self._key + 'timer__', interval, self._timer_blink, 'time') self._render(self._info['blink']) return self def _timer_blink(self, info): if info.pydata == 'time': self._info['blink'].blink = False info.pydata = 'blink' info.interval = self._info['blink'].time_interval else: self._info['blink'].blink = True info.pydata = 'time' info.interval = self._info['blink'].interval def _render(self, info): if isinstance(info.color, pygame.Surface): surface = self._font.render(self._text, 1, (255,255,255)) else: surface = self._font.render(self._text, 1, info.color) self._rect = surface.get_rect() self._anchor_position() if isinstance(info.color, pygame.Surface): info.image = gradient.apply_surface(surface, info.color) if self._angle is not None: info.r_image = pygame.transform.rotate(info.image, self._angle) self._r_rect = info.r_image.get_rect() self._r_rect.center = self._rect.center else: info.image = surface if info.alpha: twist.ghost(info.image, info.alpha) if self._angle is not None: info.r_image = pygame.transform.rotate(info.image, self._angle) self._r_rect = info.r_image.get_rect() self._r_rect.center = self._rect.center def blit(self, surface, position=None): rect = [self._r_rect, self._rect][self._angle is None] rect = self._draw_rect(rect, position) attr = ['r_image', 'image'][self._angle is None] if self._info.get('toggle', False) and self._toggle: surface.blit(getattr(self._info['toggle'], attr), rect) elif self._info.get('hover', False) and self._hover: surface.blit(getattr(self._info['hover'], attr), rect) elif self._info.get('blink', False) and self._info['blink'].blink: surface.blit(getattr(self._info['blink'], attr), rect) else: surface.blit(getattr(self._info['base'], attr), rect) def _do_render(self): for key in self._info.keys(): self._render(self._info[key]) def set_font(self, font): self._font = font self._do_render() return self def set_text(self, text): self._text = text self._do_render() return self def set_color(self, color, alpha=None): self._info['base'].set_color(color) self._info['base'].alpha = alpha self._render(self._info['base']) return self def set_position(self, x, y=None): PySceneObject.set_position(self, x, y) if self._r_rect: self._anchor_position(self_r_rect) return self def set_angle(self, angle): self._angle = angle self._do_render() return self def __repr__(self): return "Text({0})".format(self._text) RE: Is there another way to do a bunch of methods calls ? - mpd - Jan-02-2018 (Jan-02-2018, 02:55 PM)Windspar Wrote: I'm looking for another style with less typing. I agree with buran about this type of code. I think a combination of good default values and maybe a "configuration" dict or namedtuple would be the better way to approach this. This weekend, I was playing around with implementing some of the mechanics of Arkham Horror (https://www.fantasyflightgames.com/en/products/arkham-horror/) and was doing something very similar to read player/monster data from a JSON file and quickly instantiate objects. RE: Is there another way to do a bunch of methods calls ? - nilamo - Jan-02-2018 I believe this is known as the builder pattern, and is heavily used in other languages (java, rust). The idea is that the builder itself is mutable, and is used to build up an object which, when built, is immutable. Python doesn't support multi-line chaining method calls that also look good (multiline is important, as it lets you comment parts of the build out while testing, to make sure all options work properly). Instead, you can sort of accomplish the same thing using named keyword arguments. class Scene: def __init__(self, parent=None, color=None, text=None): self.parent = None self.colors = [ ] self.text = "" if parent: self.set_parent(parent) if color: self.add_color(color) if text: self.set_text(text) def set_parent(self, parent): self.parent = parent # imaginary setup # self.parent.register_child(self) def add_color(self, color): self.colors.append(color) def set_text(self, text): # only set text if there's text to set if text and text.replace(" ", ""): self.text = text menu = Scene( parent = root, color = color.GREEN, text = "Click start!", ) RE: Is there another way to do a bunch of methods calls ? - Windspar - Jan-02-2018 I was over thinking it. Probably because I keep jumping around with python and D. |