Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
lackschuh
User
Beiträge: 281 Registriert: Dienstag 8. Mai 2012, 13:40
Freitag 5. Dezember 2014, 11:32
Hallo
Ein hier häufig gelesener Satz lautet: "Nicht selber zählen, zählen lassen"
Wie zähle ich zB die Anzahl einer aufgerufenen Funktion ohne globale Variablen?
Hier habe ich es so gelöst:
Code: Alles auswählen
def counter(func):
@wraps(func)
def tmp(*args, **kwargs):
tmp.count += 1
return func(*args, **kwargs
Ein anderes Beispiel ist dieser
Thread :
Code: Alles auswählen
def motion_detected(channel):
print('Motion detected Nr.: ')
def main():
GPIO.add_event_detect(PIR_PIN, GPIO.RISING, callback=motion_detected)
# print Anzahl Aufrufe von motion_detected()
if __name__ == '__main__':
main()
lackschuh
User
Beiträge: 281 Registriert: Dienstag 8. Mai 2012, 13:40
Freitag 5. Dezember 2014, 14:56
Leider kann ich nicht mehr editieren:
Ich meine, wie kann so etwas vermieden werden im Kontext zum obigen Beispiel:
Code: Alles auswählen
count = 0
def motion_detected(channel):
global count
count = count + 1
print(count)
BlackJack
Freitag 5. Dezember 2014, 15:24
@lackschuh: Na da würde doch der Dekorator funktionieren‽
Wenn man nicht *einen* Zähler fest an die Funktion binden möchte, kann man so etwas machen:
Code: Alles auswählen
def motion_detected(channel):
print('Motion detected Nr.: ')
class CallCounter(object):
def __init__(self, function):
self.function = function
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
self.function(*args, **kwargs)
def main():
counted_motion_detected = CallCounter(motion_detected)
GPIO.add_event_detect(PIR_PIN, GPIO.RISING, callback=counted_motion_detected)
print(counted_motion_detected.count)
So könnte man dann auch die gleiche Funktion für unabhängige Bewegungssensoren verwenden.
lackschuh
User
Beiträge: 281 Registriert: Dienstag 8. Mai 2012, 13:40
Freitag 5. Dezember 2014, 15:32
@BlackJack
Danke, so könnte ich auf den Dekorator verzichten (so wie du es im anderen
Thread geschrieben hast) und die Klasse noch mit anderen Attributen vollstopfen(?)
BlackJack
Freitag 5. Dezember 2014, 16:05
@lackschuh: Die Formulierung klingt ja nicht gut.
Man könnte statt solcher generischen Sachen auch eine Klasse schreiben die einen Bewegungsensor modelliert und die dann auch gleich Thread-sicher machen. Also zum Beispiel so etwas in dieser Richtung:
Code: Alles auswählen
class MotionDetector(object):
def __init__(self, pin, callback=None):
self.pin = pin
self.callback = callback
self.lock = threading.Lock()
self.count = 0
GPIO.add_event_detect(
self.pin, GPIO.RISING, callback=self.motion_detected
)
def motion_detected(self, channel):
with self.lock:
self.count += 1
if self.callback:
self.callback(channel)
def get_and_reset_count(self):
with self.lock :
result = self.count
self.count = 0
return result
def main():
motion_detector = MotionDetector(PIR_PIN)
while True:
time.sleep(1)
print(motion_detector.get_and_reset_count())