How to build Observable/Observer pattern in Python without classes? [closed] - python

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 days ago.
Improve this question
I want to create something like "Svelte Stores" in python. Svelte stores implements the Observable (store)/Observer (subscriber) pattern in a highly composable way: a functional style, which I am trying to mimic.
In the original code, you have:
export type Subscriber<T> = (value: T) => void;
export type Unsubscriber = () => void;
export type Updater<T> = (value: T) => T;
export interface Readable<T> {
subscribe(...): Unsubscriber;
}
export interface Writable<T> extends Readable<T> {
update(this: void, updater: Updater<T>): void;
}
I tried:
from typing import Callable, TypeVar, Generic
T = TypeVar("T")
Subscriber = Callable[[T], None]
Unsubscriber = Callable[[], None]
class Store(Generic[T]):
def subscribe(self, subscriber: Subscriber[T]) -> Unsubscriber: ...
def update(self, fn: Updater[T]) -> None: ...
Store is an Observable that Subscribers(Observers) can listen. Everytime the value of the Store changes
def writable(value: T) -> Store[T]:
""" Create a writable store."""
subscriber_queue: list[Subscriber] = []
def subscribe(subscriber: Subscriber[T]) -> Unsubscriber:
subscriber_queue.append(subscriber)
subscriber(value)
def unsubscribe() -> None:
subscriber_queue.remove(subscriber)
return unsubscribe
def update(self, fn: TUpdater) -> None: fn(value)
ret = Store()
ret.subscribe = subscribe
ret.update = update
return ret
In the original implementation, writable is a factory function that creates an object (a POJO) with the subscribe and update functions. A Store (Writable in the original) is anything that has subscribe and update.
But dicts in python are different to POJOs in js.
In Python, I can't do something like:
user = writable({"name": "John", "age": 42})
name = user['name']
...,because I have no access to __getitem__ from dict.
I want to be able to access the store the same way I access an object of the type used to create the store. If I create a store with a dict which is subscriptable, I want the store to be subscriptable. If the store value is iterable, I want to be able to iterate on the store.
P.S. Edited to clarify my goal

Related

Python OOP datatype [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Why does it say 'Die eingegebenen Daten haben den falschen Datentyp!' when the datatypes are actually right? Doesn't even work with just matrNr... Although I checked my input of matrNr to be an int?!
class Student:
def __init__(self):
self.matrNr = -1
self.vorname = ''
self.nachname = ''
self.gebDatum = []
self.email = ''
self.telNr = ''
def DatenUebergeben(self, matrNr, vorname, nachname, gebDatum, telNr):
if matrNr == int and vorname == str and nachname == str and gebDatum == list and telNr == str:
print('richtige Datentypen!')
else:
print('Die eingegebenen Daten haben den falschen Datentyp!')
student1 = Student()
student1.DatenUebergeben(12345,'linda','f',[2,2,1995],'12345')
Background
By checking (for example) matrNr == int you actually compare the variable matNr, which is an int (an instance of <class 'int'>) to the class int (<class 'int'>).
Quick fix
You can use the type()-function to get the type of a variable, resulting in type(matrNr) == int. This does exactly what you are trying to achieve.
Better solution
In Python you can define the types of variables a function accepts by adding : <type> after the argument. The better solution would thus be:
def DatenUebergeben(self, matrNr: int, vorname: str, nachname: str, gebDatum: list, telNr: str):
# do something

i want to trace this method to know why it stop looping after the second record [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
i wanna to make a button to loop in all records and do a method that makes a list from ranges between tow fields and pop another record from the list and but the value in result field
i make it like in the code below and it work well just in the first record and the second record it working but without remove the record form the list and it's important for me to remove it like
then it stop working
class relate(models.Model):
_name = 'relate'
_rec_name = 'car'
#api.multi
#api.onchange('start', 'end', 'ignore')
def years_rang(self):
for rec in self.search([]):
if not rec.rang:
record = [int(x) for x in range(int(rec.start), int(rec.end) + 1)]
list = []
if rec.ignore:
try:
record.remove(int(self.ignore))
list= []
print(record)
except ValueError:
return {'warning': {'title': 'Warning!', 'message': "the Ignored year doesn't in range"}}
else:
for item in record:
range_id = self.env['yearrange'].create({'name': str(item)})
list.append(range_id.id)
rec.rang = [(4, x, None) for x in list]
else:
return
start = fields.Char(string="", required=False, )
end = fields.Char(string="", required=False, )
rang = fields.One2many(comodel_name="yearrange", inverse_name="product_id", store=True, string="Years" ,)
ignore = fields.Char(string="Ignore", required=False, )
class yearrange(models.Model):
_name = 'yearrange'
_rec_name = 'name'
name = fields.Char()
product_id = fields.Many2one(comodel_name="relate")
any kind of help will be appreciated
Adding print() in key parts helps tracing a lot.
If more is needed, import pdb; pdb.set_trace() would get you into a debugger REPL, provided that the process has a terminal (not running in a Lambda, etc).
The lack of explanation of what this code is doing and what kind of data it works on prevents an uninvolved observer from detecting any data-related bugs in it. What does self.search([]) even return?
Shadowing built-in identifiers like list is a bad idea, about as bad as having non-descriptive names like list.

Looking for a better code pattern to implement user input validation in Python Cmd implementatiion [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I am a new with Python (very experienced in Java) and I am coding an application using the cmd package. Implementations of Cmd class will create methods like the one below (pattern "do_*") to respond to user input.
I have one such method that looks like the following. In particular in the spirit of DRY I don't like having to repeat the same print/return sequence 3 times.
Is there a more Pythonesque code pattern that would be more elegant or have I done it correctly?
def do_addvlan(self, arg):
'Add a VLAN. Usage: addvlan <number> <name>'
args = arg.split()
if len(args) < 1:
print("Err: VLAN needs to be 0 to 4095")
return
try:
vlan = int(args[0])
except ValueError:
print("Err: VLAN needs to be 0 to 4095")
return
if vlan < 0 or vlan > 4095:
print("Err: VLAN needs to be 0 to 4095")
return
print("OK I will add VLAN %d" % vlan)
Your question's somewhat vague about what how vlan gets "added", but you could use a class decorator to add do_VLAN sorts of methods to a cmd.Cmd subclass similar to what you command does in the example code. Passing explicit arguments to a decorator requires essentially writing a decorator factory which creates a regular decorator using the parameters passed and returns it.
Here's what I'm talking about:
import cmd
def add_cmd(attr, kind, lo, hi, doc=""):
def decorator(cls):
def do_cmd(self, args):
args = args.split()
if len(args) != 1:
print("Err: {} needs one argument".format(attr))
return
try:
value = kind(args[0])
except ValueError:
print("Err: {} argument needs to be of type {}".format(attr, kind))
return
if not (lo <= value <= hi):
print("Err: {} argument needs to be range {} to {}".format(attr, lo, hi))
return
print("Adding attribute {} = {}".format(attr, value))
setattr(self, attr, value)
self.__dict__.setdefault("_added", []).append(attr)
# override method's special attributes
func_name = "do_" + attr
setattr(do_cmd, "__name__", func_name)
setattr(do_cmd, "__module__", cls.__module__)
if doc: setattr(do_cmd, "__doc__", doc)
setattr(cls, func_name, do_cmd) # add method created to class
return cls
return decorator
if __name__ == '__main__':
#add_cmd("VLAN", int, 0, 4095, "Adds VLAN attribute between 0-4095")
#add_cmd("WEIGHT", float, 0, 1000, "Adds WEIGHT attribute between 0-1000")
class MyCmd(cmd.Cmd):
prompt = "MyCmd> "
def do_SHOW(self, line):
"Shows what attributes have been added so far"
added = getattr(self, "_added", None)
if not added:
print("No attributes have been added yet.")
else:
print("Added attributes:")
for attr in added:
print(" {}: {}".format(attr, getattr(self, attr)))
def do_EOF(self, line):
print("Exiting")
return True
MyCmd().cmdloop()
This is the output generated from running it in console session demonstrating that it works:
>python "looking-for-a-better-code-pattern-to-implement-user-input-validation.py"
MyCmd> help
Documented commands (type help <topic>):
========================================
SHOW VLAN WEIGHT help
Undocumented commands:
======================
EOF
MyCmd> help VLAN
Adds VLAN attribute between 0-4095
MyCmd> help WEIGHT
Adds WEIGHT attribute between 0-1000
MyCmd> help SHOW
Shows what attributes have been added so far
MyCmd> VLAN 42
Adding attribute VLAN = 42
MyCmd> WEIGHT 3.1415
Adding attribute WEIGHT = 3.1415
MyCmd> SHOW
Added attributes:
VLAN: 42
WEIGHT: 3.1415
MyCmd> ^Z
Exiting
>

Python Best Practices: Pass to Method or Instance Variable [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
In Python, should I be writing my methods like option 1 or option 2 in the code below? Thanks!
from someHardware import someHardware
# Option 1, pass the data into method
class SomeClass:
def getValue( self ):
rawData = someHardware.getData()
return self.calculateValue( rawData )
def calculateValue( self, rawData ):
return ( rawData * 100 ) - 5
# Option 2, save data as instance variable
class SomeClass:
def getValue( self ):
self.rawData = someHardware.getData()
return self.calculateValue()
def calculateValue( self ):
return ( self.rawData * 100 ) - 5
If your method is called calculateValue, definitively give it something to calculate on, that's semantically clearer. Also, that method is public (no _ to mark it as not-API), so it should make sense to call it externally.
Also, if you do that, your calculateValue will be independent from self, making it basically a staticmethod, thus:
class SomeClass:
def getValue( self ):
rawData = someHardware.getData()
return self.calculateValue( rawData )
#staticmethod
def calculateValue( rawData ):
return ( rawData * 100 ) - 5
Will make it clearer.

How to call/run a method only one time in python [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I want to call/run a method only onetime I tried this but it didn't wotk:
class S ()
_int_(self)
self.xxx = True # i tried with and without
def Packet (event):
if (xxx == True):
self.f(event, xxx)
print xxx
else:
....
def f (event):
print "something"
Do_Somthing
xxx=False
the problem xxx is still true
Best regards
Amer
The whole class's syntax seems wrong to me. You can do something like this
class S:
def __init__(self): # Initializer function for instance members
self.flag = True
def myMethod(self): # Actual method to be called
if self.flag:
....
....
self.flag = False
Change xxx to self.xxx.
The xxx = False creates a new name binding instead of assigning to the field in your object.
Also, there are also some other syntax errors in your code. Is this the actual code you are running? The code you posted shouldn't run.
from itertools import count
class S ()
def __init__(self)
self.xxx = count()
def Packet(self, event):
if next(self.xxx) == 0:
self.f(event)
else:
....
def f(self, event):
print "something"
#Do_Something

Categories

Resources