@harryberlin: Ein ganz wichtiger Rat wäre: Lass die Finger von `__del__()`! Es ist nicht garantiert wann und ob die Methode aufgerufen wird und ihr Vorhandensein kann sogar begünstigen das sie nie aufgerufen wird. Die Methode sollte man nur implementieren wenn man genau weiss was die Speicherverwaltung von Python garantiert und was *nicht*, und dann auch nur wenn man externe Ressourcen verwalten muss, von denen Python nichts weiss. Das ist hier nicht der Fall soweit ich das sehe.
Wenn man `Thread` in einer Klasse verwendet um in einer `start()`-Methode eine andere Methode in dieser Klasse asynchron zu starten, wäre es einfacher diese andere Methode `run()` zu nennen und von `Thread` zu erben.
Der Receiver kann so wie er da steht soweit ich das sehe nur von einer Gegenstelle einmal eine Verbindung annehmen und bearbeiten.
Ist das überhaupt das was Du tatsächlich laufen lässt? Denn in Zeile 60 sollte es einen `AttributeError` geben weil `CmdSender` gar kein `run`-Attribut kennt.
Zugriff auf Modul welches bereits aktiv ist
-
- User
- Beiträge: 227
- Registriert: Donnerstag 17. Dezember 2015, 12:17
ok, del fliegt raus.
run oder start, da war ich tatsächlich hin und her gerissen
das mit der thread vererbung versteh ich grad nicht.
und ja du hast recht, das wäre dann als nächstes meine frage gewesen.
wenn die verbindung unterbrochen wird, müsste man es wieder starten.
gibt es bessere lösungen?
das mit zmq und argparse hab ich auch versucht, aber es passiert genauso nix.
run oder start, da war ich tatsächlich hin und her gerissen
das mit der thread vererbung versteh ich grad nicht.
und ja du hast recht, das wäre dann als nächstes meine frage gewesen.
wenn die verbindung unterbrochen wird, müsste man es wieder starten.
gibt es bessere lösungen?
das mit zmq und argparse hab ich auch versucht, aber es passiert genauso nix.
empty Sig
-
- User
- Beiträge: 227
- Registriert: Donnerstag 17. Dezember 2015, 12:17
ich glaub ich habs
zwar noch nicht als klasse, aber ich sehe etwas.
und das müsste dann auch ohne verbindungsunterbrechung laufen.
edit:
hab über die Thread-Vererbung noch mal drüber nachgedacht, meinst du das so?
jetzt mal schnell hier runter geschrieben.
Bin mit classen nicht so bewandert.
zwar noch nicht als klasse, aber ich sehe etwas.
und das müsste dann auch ohne verbindungsunterbrechung laufen.
Code: Alles auswählen
import zmq
from threading import Thread
def server_run():
# server
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind('tcp://127.0.0.1:5555')
while True:
msg = socket.recv()
if msg == 'zeromq':
socket.send('ah ha!')
else:
socket.send('...nah')
def client_send(msg):
# client
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect('tcp://127.0.0.1:5555')
socket.send(msg)
msg = socket.recv()
print msg
Thread(target=server_run).start()
client_send('zeromq')
hab über die Thread-Vererbung noch mal drüber nachgedacht, meinst du das so?
jetzt mal schnell hier runter geschrieben.
Bin mit classen nicht so bewandert.
Code: Alles auswählen
class CmdReceiver(Thread):
def __ini__(self):
self.target = run
self.run = True
def start(self):
self.start()
def run(self):
while self.run:
pass
def stop(self):
self.run = False
empty Sig
@harryberlin: Mit von `Thread` erben war gemeint von `Thread` zu erben (ungetestet):
Code: Alles auswählen
from __future__ import absolute_import, division, print_function
from contextlib import closing
from threading import Thread
# ...
class CmdReceiver(Thread):
def __init__(self):
print('server init')
Thread.__init__(self)
self.address = ('localhost', 6000)
self.stop_requested = False
self.listener = None
def run(self):
print('server start')
with closing(
Listener(self.address, authkey='bmwibus')
) as self.listener:
with closing(self.listener.accept()) as connection:
print(
'server connection accepted from',
self.listener.last_accepted
)
while not self.stop_requested:
message = connection.recv()
#
# Do something with `message`.
#
print(message)
if message == 'close':
break
def stop(self):
print('server stop')
self.stop_requested = True
self.listener.close()
-
- User
- Beiträge: 227
- Registriert: Donnerstag 17. Dezember 2015, 12:17
ich glaub ich bleib bei zmq, weil "multiprocessing.connection" vermutlich auch nur eine verbindung zulässt.
zmq müsste ja auch mehrere clients zulassen.
zur klasse:
Ok bei Thread.__init__(self) komm ich noch mit, dass er sich sozusagen einrichtet.
Aber legt der dann gleich los und weiß auch was auszuführen ist?
Ich sehe nirgends ein target oder start()
zmq müsste ja auch mehrere clients zulassen.
zur klasse:
Ok bei Thread.__init__(self) komm ich noch mit, dass er sich sozusagen einrichtet.
Aber legt der dann gleich los und weiß auch was auszuführen ist?
Ich sehe nirgends ein target oder start()
empty Sig
@harryberlin: Dann schau mal in die Dokumentation zu `Thread`, da findest Du die `start()`-Methode. Ich glaube Du solltest Dich noch mal mit Klassen und Vererbung auseinandersetzen.
-
- User
- Beiträge: 227
- Registriert: Donnerstag 17. Dezember 2015, 12:17
hab die docu hier gefunden:
http://pythoncentral.io/how-to-create-a ... in-python/
Ich weiß nun zwar was ich bei Thread machen muss, aber irgendwie fällt der groschen bei mir nicht, wenn es um klassen geht.
gibts irgendwo sowas wie "python klassen für dummies" auf deutsch?
edit:
hab ein ebook gefunden
http://pythoncentral.io/how-to-create-a ... in-python/
Ich weiß nun zwar was ich bei Thread machen muss, aber irgendwie fällt der groschen bei mir nicht, wenn es um klassen geht.
gibts irgendwo sowas wie "python klassen für dummies" auf deutsch?
edit:
hab ein ebook gefunden
empty Sig
@harryberlin: Die Dokumentation von `Thread` befindet sich in der Dokumentation von Python, da muss man nicht irgendwo im Internet nach suchen. Klassen sollten im Tutorial in der Python-Dokumentation auch vorkommen.
-
- User
- Beiträge: 227
- Registriert: Donnerstag 17. Dezember 2015, 12:17
ich hab nun mal was zusammen gezaubert.
kann ich das mit dem start() beim init machen, oder rät man eher davon ab?
schon mal in vorbereitung mit rückgabewert.
was hälst sonst davon.
kann ich das mit dem start() beim init machen, oder rät man eher davon ab?
schon mal in vorbereitung mit rückgabewert.
was hälst sonst davon.
Code: Alles auswählen
from threading import Thread
import zmq
class tcp_server(Thread):
def __init__(self):
Thread.__init__(self)
self.stopserver = False
context = zmq.Context()
self.socket = context.socket(zmq.REP)
self.socket.bind('tcp://127.0.0.1:5555')
self.start()
def run(self):
while not self.stopserver:
message = self.socket.recv()
if message == 'stop_server':
self.stop()
else:
self.onMessage(message)
def stop(self):
self.stopserver = True
self.socket.close()
self.join()
def onMessage(self, message):
print 'SERVER: Handle Message'
self.socket.send('ok')
pass
class tcp_client:
def __init__(self):
context = zmq.Context()
self.socket = context.socket(zmq.REQ)
self.socket.connect('tcp://127.0.0.1:5555')
def send(self, message):
print message
self.socket.send(message)
message = self.socket.recv()
print message
return message
msg_server = tcp_server()
tcp_client().send('test')
empty Sig
@harryberlin: wenn Du den Thread schon in __init__ startest, verbaust Du Dir die Flexibilität, den Thread anderweitig zu starten. Nicht zuletzt gibt es ja die extra Methode start. Starte den Thread also außerhalb von __init__ im Hauptprogramm. Den zmq-Server würde ich erst in run starten.
-
- User
- Beiträge: 227
- Registriert: Donnerstag 17. Dezember 2015, 12:17
ok.
sollte ich zum schließen der sockets noch was spezielles beachten?
reicht close() oder auch noch unbind()?
oder ist unbind() sinnvoll, um einen evtl. blockierten port wieder frei zu kriegen?
sollte ich zum schließen der sockets noch was spezielles beachten?
reicht close() oder auch noch unbind()?
oder ist unbind() sinnvoll, um einen evtl. blockierten port wieder frei zu kriegen?
empty Sig
-
- User
- Beiträge: 227
- Registriert: Donnerstag 17. Dezember 2015, 12:17
ich hab jetzt mal bissl mit zmq herumgespielt.
aber habe ein problem, wenn man send oder recv ausführt, bleibt der client oder server im code stehen, wenn die andere seite nicht vorhanden ist bzw. reagiert.
entsprechend lässt sich auch der thread nicht beenden.
irgendwie blöd.
aber habe ein problem, wenn man send oder recv ausführt, bleibt der client oder server im code stehen, wenn die andere seite nicht vorhanden ist bzw. reagiert.
entsprechend lässt sich auch der thread nicht beenden.
irgendwie blöd.
empty Sig
-
- User
- Beiträge: 227
- Registriert: Donnerstag 17. Dezember 2015, 12:17
OK, jetzt hab ich grad gesehn, dass mein thema wohl besser unter netzwerkprogrammierung aufgehoben wäre.
deswegen gehts hier eher in eine alleinunterhaltung....
hab nun mal bissl herum experimentiert und folgendes geschrieben (ja auch c&p)
bin jetzt noch über diesen link hier gestolpert, ich glaub da kann einiges an code eingespart werden.:
viewtopic.php?f=3&t=36933
https://docs.python.org/2/library/socketserver.html
deswegen gehts hier eher in eine alleinunterhaltung....
hab nun mal bissl herum experimentiert und folgendes geschrieben (ja auch c&p)
bin jetzt noch über diesen link hier gestolpert, ich glaub da kann einiges an code eingespart werden.:
viewtopic.php?f=3&t=36933
https://docs.python.org/2/library/socketserver.html
Code: Alles auswählen
from threading import Thread
import socket
import time
class tcp_server(Thread):
def __init__(self):
Thread.__init__(self)
self.stopserver = False
self.start()
def run(self):
# Create a TCP/IP socket
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Bind the socket to the port
server_address = ('localhost', 10000)
print 'starting up on %s port %s' % server_address
self.sock.bind(server_address)
# Listen for incoming connections
self.sock.listen(1)
self.sock.settimeout(0.1)
while not self.stopserver:
# Wait for a connection
#print 'SERVER: waiting for a connection'
try:
self.connection, client_address = self.sock.accept()
try:
print 'SERVER: connection from', client_address
# Receive the data in small chunks and retransmit it
data = self.connection.recv(50)
print 'SERVER: received "%s"' % data
if data:
self.onMessage(data)
finally:
# Clean up the connection
self.connection.close()
except:
pass
def stop(self):
print 'SERVER: Close'
self.stopserver = True
self.connection.close()
self.sock.close()
self.join(0)
def onMessage(self, message):
print 'SERVER: Handle Message "%s"' % message
self.connection.sendall('ok')
pass
class tcp_client:
def __init__(self):
pass
def send(self, message):
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect the socket to the port where the server is listening
server_address = ('localhost', 10000)
print 'CLIENT: Try to connect %s port %s' % server_address
if sock.connect_ex(server_address) != 0:
print 'CLIENT: Connection to server is not possible'
return False
try:
# Send data
print 'CLIENT: sending "%s"' % message
sock.sendall(message)
# Look for the response
data = sock.recv(50)
print 'CLIENT: response from server "%s"' % data
except:
print 'CLIENT: Error by sending'
return False
finally:
print 'CLIENT: Close'
sock.close()
return True
tcp_srv = tcp_server()
tcp_client().send('This is the message.')
time.sleep(0.5)
tcp_srv.stop()
del tcp_srv
time.sleep(0.5)
tcp_client().send('test2')
print('end')
pass
empty Sig
@harryberlin: Auf Modulebene sollte kein Code stehen der nicht Konstanten, Funktionen, oder Klassen definiert. Das Hauptprogramm steht üblicherweise in einer `main()`-Funktion.
Die Namensgebung folgt nicht immer dem Style Guide for Python Code. Gerade bei Klassen sollte man nicht abweichen, damit der Leser sie als Klassen erkennen kann.
Das man `start()` nicht in der `__init__()` von `Thread`-Unterklassen aufrufen sollte hatten wir glaube ich schon etwas weiter oben.
Attribute sollten nicht ausserhalb der `__init__()` eingeführt werden. Ein Objekt sollte nach deren Abarbeitung in der Regel einem vollständigen und benutzbaren Zustand sein und ein Leser sollte nicht die gesamte Klasse lesen müssen um zu wissen welche Attribute die Objekte am Ende haben. Wenn man bei der Initialisierung noch keine entgültigen Werte zuweisen kann, dann kann man `None` an die Attribute binden.
Es gibt drei überflüssige ``pass``-Anweisungen und eine die zwar syntaktisch richtig ist, dort aber trotzdem nicht als Behandlung in einem ”nackten” ``except:``-Zweig stehen sollte. Dort ”behandelst” Du *jede* Ausnahme durch nichtstun, was sicher nicht bei *jeder* Ausnahme die richtige Behandlung ist. Eigentlich ja nur bei der die Du dort erwartest, nämlich die Zeitüberschreitung vom `accept()` auf dem Serversocket. Dann sollte man das aber auch so schreiben. Ausserdem sollte man den ``try``-Block auf das nötigste beschränken um nicht irgendwann Ausnahmen zu behandeln, die man eigentlich gar nicht erwartet hat weil sie von einer anderen Stelle des ``try``-Blocks oder einer dort aufgerufenen Operation stammen. Dabei hilft ein ``else``-Zweig beim ``try``/``except``-Konstrukt.
Der Kommentar ``# Receive the data in small chunks and retransmit it`` ist falsch weil der Code etwas anderes macht. Und der Code ist falsch weil der `recv()` irgendetwas zwischen einem und 50 Bytes aus dem Datenstrom liest, die nicht die gesamten Daten ausmachen müssen, die der Client gesendet hat. Die Namen `onMessage()` und `message` sind hier irreführend weil Du nirgends sicherstellst, das es sich um die oder eine komplette Nachricht handelt. Korrekter Socket-Code muss an der Stelle im Extremfall damit klar kommen, dass jeder `recv()`-Aufruf nur ein einziges Byte liefert, man die Methode also tatsächlich so oft aufrufen muss, wie Bytes in der Nachricht gesendet wurden. Dazu muss man irgendwie erkennen können wann eine Nachricht komplett ist. Zum Beispiel weil die Verbindung vom Sender (halb) geschlossen wird wenn er alles gesendet hat, oder weil alle Nachrichten eine feste Grösse haben, oder mit einer bestimmten Bytefolge abgeschlossen sind, die innerhalb der Nachricht nicht vorkommen kann, oder weil am Anfang die Grösse der Nachricht übermittelt wurde. Die Grösse dann auch wieder entweder durch eine bestimmte Bytefolge abgeschlossen, die nicht innerhalb der Grössenangabe vorkommen kann, oder in einer festen Byteanzahl.
`tcp_client` ist keine Klasse. Die `__init__()` ist leer (``pass``), kann also weg, womit nur noch eine einzige ”Methode” übrigbleibt, welche das Objekt auf dem sie definiert ist, nicht verwendet, und die jedes mal direkt nach dem erstellen eines Exemplars aufgerufen wird und das Exemplar wird nach dem Aufruf auch gleich wieder verworfen. Damit ist das alles nur eine sehr umständliche Art eine Funktion zu schreiben und aufzurufen.
Die Fehlerbehandlung in der Funktion ist schlecht. Du vermeidest Ausnahmen oder wandelst sie in einen `bool`-Rückgabewert um. Und dieser Rückgabewert wird nirgends geprüft, also genau das weshalb man Ausnahmen erfunden hat: Damit man keine speziellen Rückgabewerte prüfen muss und *vergessen* kann das zu tun.
``del`` auf einen Namen anzuwenden macht hier nicht viel Sinn. Das löscht den *Namen*, *nicht* das Objekt.
Ich komme dann ungefähr auf das hier:
Die Namensgebung folgt nicht immer dem Style Guide for Python Code. Gerade bei Klassen sollte man nicht abweichen, damit der Leser sie als Klassen erkennen kann.
Das man `start()` nicht in der `__init__()` von `Thread`-Unterklassen aufrufen sollte hatten wir glaube ich schon etwas weiter oben.
Attribute sollten nicht ausserhalb der `__init__()` eingeführt werden. Ein Objekt sollte nach deren Abarbeitung in der Regel einem vollständigen und benutzbaren Zustand sein und ein Leser sollte nicht die gesamte Klasse lesen müssen um zu wissen welche Attribute die Objekte am Ende haben. Wenn man bei der Initialisierung noch keine entgültigen Werte zuweisen kann, dann kann man `None` an die Attribute binden.
Es gibt drei überflüssige ``pass``-Anweisungen und eine die zwar syntaktisch richtig ist, dort aber trotzdem nicht als Behandlung in einem ”nackten” ``except:``-Zweig stehen sollte. Dort ”behandelst” Du *jede* Ausnahme durch nichtstun, was sicher nicht bei *jeder* Ausnahme die richtige Behandlung ist. Eigentlich ja nur bei der die Du dort erwartest, nämlich die Zeitüberschreitung vom `accept()` auf dem Serversocket. Dann sollte man das aber auch so schreiben. Ausserdem sollte man den ``try``-Block auf das nötigste beschränken um nicht irgendwann Ausnahmen zu behandeln, die man eigentlich gar nicht erwartet hat weil sie von einer anderen Stelle des ``try``-Blocks oder einer dort aufgerufenen Operation stammen. Dabei hilft ein ``else``-Zweig beim ``try``/``except``-Konstrukt.
Der Kommentar ``# Receive the data in small chunks and retransmit it`` ist falsch weil der Code etwas anderes macht. Und der Code ist falsch weil der `recv()` irgendetwas zwischen einem und 50 Bytes aus dem Datenstrom liest, die nicht die gesamten Daten ausmachen müssen, die der Client gesendet hat. Die Namen `onMessage()` und `message` sind hier irreführend weil Du nirgends sicherstellst, das es sich um die oder eine komplette Nachricht handelt. Korrekter Socket-Code muss an der Stelle im Extremfall damit klar kommen, dass jeder `recv()`-Aufruf nur ein einziges Byte liefert, man die Methode also tatsächlich so oft aufrufen muss, wie Bytes in der Nachricht gesendet wurden. Dazu muss man irgendwie erkennen können wann eine Nachricht komplett ist. Zum Beispiel weil die Verbindung vom Sender (halb) geschlossen wird wenn er alles gesendet hat, oder weil alle Nachrichten eine feste Grösse haben, oder mit einer bestimmten Bytefolge abgeschlossen sind, die innerhalb der Nachricht nicht vorkommen kann, oder weil am Anfang die Grösse der Nachricht übermittelt wurde. Die Grösse dann auch wieder entweder durch eine bestimmte Bytefolge abgeschlossen, die nicht innerhalb der Grössenangabe vorkommen kann, oder in einer festen Byteanzahl.
`tcp_client` ist keine Klasse. Die `__init__()` ist leer (``pass``), kann also weg, womit nur noch eine einzige ”Methode” übrigbleibt, welche das Objekt auf dem sie definiert ist, nicht verwendet, und die jedes mal direkt nach dem erstellen eines Exemplars aufgerufen wird und das Exemplar wird nach dem Aufruf auch gleich wieder verworfen. Damit ist das alles nur eine sehr umständliche Art eine Funktion zu schreiben und aufzurufen.
Die Fehlerbehandlung in der Funktion ist schlecht. Du vermeidest Ausnahmen oder wandelst sie in einen `bool`-Rückgabewert um. Und dieser Rückgabewert wird nirgends geprüft, also genau das weshalb man Ausnahmen erfunden hat: Damit man keine speziellen Rückgabewerte prüfen muss und *vergessen* kann das zu tun.
``del`` auf einen Namen anzuwenden macht hier nicht viel Sinn. Das löscht den *Namen*, *nicht* das Objekt.
Ich komme dann ungefähr auf das hier:
Code: Alles auswählen
import socket
import time
from contextlib import closing
from threading import Thread
SERVER_ADDRESS = ('localhost', 10001)
class TCPServer(Thread):
def __init__(self):
Thread.__init__(self)
self.stop_requested = False
self.server_socket = None
self.connection = None
def run(self):
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print 'SERVER: starting up on %s port %s' % SERVER_ADDRESS
self.server_socket.bind(SERVER_ADDRESS)
self.server_socket.listen(1)
self.server_socket.settimeout(0.1)
while not self.stop_requested:
try:
self.connection, client_address = self.server_socket.accept()
except socket.timeout:
pass # Intentionally ignored.
else:
print 'SERVER: connection from', client_address
with closing(self.connection):
data = self.connection.makefile().read()
print 'SERVER: received %r' % data
if data:
self.on_message(data)
def stop(self):
print 'SERVER: Close'
self.stop_requested = True
self.server_socket.close()
self.connection.close()
self.join()
def on_message(self, message):
print 'SERVER: Handle Message %r' % message
self.connection.sendall('ok')
def send(message):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'CLIENT: Try to connect %s port %s' % SERVER_ADDRESS
sock.connect(SERVER_ADDRESS)
with closing(sock):
print 'CLIENT: sending %r' % message
sock.sendall(message)
sock.shutdown(socket.SHUT_WR)
data = sock.makefile().read()
print 'CLIENT: response from server %r' % data
print 'CLIENT: Close'
def main():
tcp_server = TCPServer()
tcp_server.daemon = True
tcp_server.start()
time.sleep(0.5) # Wait for server to start.
send('This is the message.')
time.sleep(0.5)
tcp_server.stop()
time.sleep(0.5)
send('test2')
print 'end'
if __name__ == '__main__':
main()
-
- User
- Beiträge: 227
- Registriert: Donnerstag 17. Dezember 2015, 12:17
uff, ich werte es mal wieder als klatsche.
hast du für diese analysen auswertungen ein tool?
darf ich fragen, was du beruflich machst?
hast du für diese analysen auswertungen ein tool?
darf ich fragen, was du beruflich machst?
empty Sig
@harryberlin: „Klatsche“ klingt ein bisschen hart. Sieh's als konstruktive Kritik.
Es gibt mehrere Werkzeuge, die Python-Code statisch analysieren, oder es zumindest versuchen. Das klappt für so einfache Sachen wie die Namensschreibweisen oder überflüssige ``pass``-Anweisungen sehr gut (wobei man das natürlich auch ohne ein Werkzeug leicht sehen kann wenn man den Quelltext durchliest), und für Sachen die mit Attributen und Vererbung zu tun haben, so gut wie es eben bei einer dynamisch typisierten Programmiersprache geht. Die verbreitetsten Werkzeuge dürften `pep8`, `pyflakes`, und `pylint` sein. In vernünftigen™ Editoren und IDEs kann man so etwas auch integrieren, so dass man auf Knopfdruck oder automatisch beim Speichern einen Analyselauf anstossen kann, und das Ergebnis irgendwie sinnvoll präsentiert wird.
Semantische Sachen wie `start()` in der `Thread.__init__()`, die falsche Verwendung von Sockets, oder irreführende Namen weil deren Bedeutung nicht zu dem passt wofür sie stehen, kann der Rechner nicht automatisch finden. Wenn er so etwas könnte, währen wir wahrscheinlich nicht weit von Rechnern entfernt die sich selber programmieren. Da lauert dann der Terminator um die Ecke.
Beruflich programmiere ich viel. Welch eine Überraschung.
Es gibt mehrere Werkzeuge, die Python-Code statisch analysieren, oder es zumindest versuchen. Das klappt für so einfache Sachen wie die Namensschreibweisen oder überflüssige ``pass``-Anweisungen sehr gut (wobei man das natürlich auch ohne ein Werkzeug leicht sehen kann wenn man den Quelltext durchliest), und für Sachen die mit Attributen und Vererbung zu tun haben, so gut wie es eben bei einer dynamisch typisierten Programmiersprache geht. Die verbreitetsten Werkzeuge dürften `pep8`, `pyflakes`, und `pylint` sein. In vernünftigen™ Editoren und IDEs kann man so etwas auch integrieren, so dass man auf Knopfdruck oder automatisch beim Speichern einen Analyselauf anstossen kann, und das Ergebnis irgendwie sinnvoll präsentiert wird.
Semantische Sachen wie `start()` in der `Thread.__init__()`, die falsche Verwendung von Sockets, oder irreführende Namen weil deren Bedeutung nicht zu dem passt wofür sie stehen, kann der Rechner nicht automatisch finden. Wenn er so etwas könnte, währen wir wahrscheinlich nicht weit von Rechnern entfernt die sich selber programmieren. Da lauert dann der Terminator um die Ecke.
Beruflich programmiere ich viel. Welch eine Überraschung.
-
- User
- Beiträge: 227
- Registriert: Donnerstag 17. Dezember 2015, 12:17
zukünftig wird aus dem script zwei. das war der hintergrund, zwischen modulen zu arbeiten.
deswegen adresse und port direkt in der funktion.
woran kann man variablen und konstanten erkennen?
welchen zweck hat jetzt das closing?
die client klasse habe ich wie gesagt, weil mir nahe gelegt wurde ich soll es so machen. lässt sich später auch mal einfacher importieren.
noch ne Verständnisfrage, weil ich ständig module, functionen und methoden lese:
wie definiert ihr das?
ebenso bei argumenten und eigenschaften.
deswegen adresse und port direkt in der funktion.
woran kann man variablen und konstanten erkennen?
welchen zweck hat jetzt das closing?
die client klasse habe ich wie gesagt, weil mir nahe gelegt wurde ich soll es so machen. lässt sich später auch mal einfacher importieren.
noch ne Verständnisfrage, weil ich ständig module, functionen und methoden lese:
wie definiert ihr das?
ebenso bei argumenten und eigenschaften.
empty Sig
@harryberlin: Variablen sind veränderbar, also variabel, und Konstanten bleiben immer gleich, also konstant. Variablen haben auf Modulebene nichts zu suchen und Konstanten werden per Konvention komplett in Grossbuchstaben geschrieben, damit man beim Lesen weiss das sich der Wert nicht ändert.
Was ist an der Dokumentation zu `contextlib.closing()` denn konkret unklar?
Bei der Client-Klasse würde ich eher nahelegen es *nicht* so zu machen, eben weil es semantisch keine Klasse ist.
Module, Funktionen, Methoden, und Argumente definieren wir so wie Python das tut. Wobei Funktionen, Methoden, und Argumente auch generell Begriffe aus der Programmierung sind und von sehr vielen Programmiersprachen gleich oder sehr ähnlich definiert werden. Das sollte eigentlich alles in einem Python-Tutorial oder -Buch stehen. Allgemein hilft Wikipedia auch oft was Programmierbegriffe angeht. Kurze Definitionen zu den Begriffen aus Python-Sicht finden sich in der Python-Dokumentation im Glossar.
Eigenschaften ist ein Begriff der ein bisschen mehrdeutig ist. Zum einen gibt es die ganz normale Bedeutung des Wortes im Deutschen. Und dann wird der Begriff auch für das gebraucht was man in Python mit `property()` erstellt.
Was ist an der Dokumentation zu `contextlib.closing()` denn konkret unklar?
Bei der Client-Klasse würde ich eher nahelegen es *nicht* so zu machen, eben weil es semantisch keine Klasse ist.
Module, Funktionen, Methoden, und Argumente definieren wir so wie Python das tut. Wobei Funktionen, Methoden, und Argumente auch generell Begriffe aus der Programmierung sind und von sehr vielen Programmiersprachen gleich oder sehr ähnlich definiert werden. Das sollte eigentlich alles in einem Python-Tutorial oder -Buch stehen. Allgemein hilft Wikipedia auch oft was Programmierbegriffe angeht. Kurze Definitionen zu den Begriffen aus Python-Sicht finden sich in der Python-Dokumentation im Glossar.
Eigenschaften ist ein Begriff der ein bisschen mehrdeutig ist. Zum einen gibt es die ganz normale Bedeutung des Wortes im Deutschen. Und dann wird der Begriff auch für das gebraucht was man in Python mit `property()` erstellt.
-
- User
- Beiträge: 227
- Registriert: Donnerstag 17. Dezember 2015, 12:17
komisch, irgendwie reden wir immer aneinander vorbei.
1. d.h. sobald ein name in großbuchenstaben definiert ist, dann gilt es für python als konstante deklariert?
2. irgendwas muss dich doch dazu bewegt haben, "closing" rein zu nehmen. dass ich mir die manual dazu durchlese, kann ich mir nicht vorstellen.
geht damit etwas besser als zuvor?
3. Das Nutzen von Klassen hat mir BJ1 aus'm Kodinerds Forum ans Herz gelegt. Kennste bestimmt
4. Zu den Definitionen aus meiner Sicht:
Modul: das Python File, was Klassen, Funktionen, Konstanten, Variablen enthalten kann. Sprich auch importiert werden kann.
Funktionen: Methode, Function, wobei ich auch schon gelesen hab, dass functionen als Objekt betitelt wurden in Bezug auf OOP.
Eigenschaften: Variablen oder Konstanten innerhalb Klassen.
Argumente: werden für Funktionen übergeben.
Property: Ok wieder was neues, muss ich mich mal belesen.
Widersprüchliches oder Richtigstellung bitte dazu schreiben, sollte ich falsches Verständnis haben.
1. d.h. sobald ein name in großbuchenstaben definiert ist, dann gilt es für python als konstante deklariert?
2. irgendwas muss dich doch dazu bewegt haben, "closing" rein zu nehmen. dass ich mir die manual dazu durchlese, kann ich mir nicht vorstellen.
geht damit etwas besser als zuvor?
3. Das Nutzen von Klassen hat mir BJ1 aus'm Kodinerds Forum ans Herz gelegt. Kennste bestimmt
4. Zu den Definitionen aus meiner Sicht:
Modul: das Python File, was Klassen, Funktionen, Konstanten, Variablen enthalten kann. Sprich auch importiert werden kann.
Funktionen: Methode, Function, wobei ich auch schon gelesen hab, dass functionen als Objekt betitelt wurden in Bezug auf OOP.
Eigenschaften: Variablen oder Konstanten innerhalb Klassen.
Argumente: werden für Funktionen übergeben.
Property: Ok wieder was neues, muss ich mich mal belesen.
Widersprüchliches oder Richtigstellung bitte dazu schreiben, sollte ich falsches Verständnis haben.
empty Sig
- pillmuncher
- User
- Beiträge: 1484
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
Nein, er gilt für den Programmierer als Konstante. Dem Python ist das wurst, aber wenn ich als Programmierer einen solchen Namen im Pythoncode sehe, erwarte ich, dass er als Konstante verwendet wird, qua Konvention. In Python ist sehr vieles reine Konvention. Mehr dazu in PEP8.harryberlin hat geschrieben:1. d.h. sobald ein name in großbuchenstaben definiert ist, dann gilt es für python als konstante deklariert?
In specifications, Murphy's Law supersedes Ohm's.