2016-11-15 4 views
0

Also habe ich versucht, die Verwendung einer Klassenkonstante zu verstehen, aber ich sehe nicht, wie dies überschrieben werden kann. Wenn meine Bibliothek wie folgt aussehen:Überschreiben von Konstanten beim Importieren

class ArcsightLogger(object): 
    """ 
    Main Class to interact with Arcsight Logger REST API 
    """ 

    TARGET = 'https://SOMETHING:9000' 

    def __init__(self, username, password, disable_insecure_warning=False): 
     """ 
     Log in the user whose credentials are provided and 
     store the access token to be used with all requests 
     against Arcsight 
     """ 

     action = 'ignore' if disable_insecure_warning else 'once' 
     warnings.simplefilter(action, InsecureRequestWarning) 
     r = self._post(
      '/core-service/rest/LoginService/login', data={ 
       'login': username, 
       'password': password, 
      }, is_json=False) 
     r.raise_for_status() 
     loginrequest = untangle.parse(r.content) 
     self.token = loginrequest.ns3_loginResponse.ns3_return.cdata 

    def format_time(self, *args): 
     currentdt = datetime.datetime.now(pytz.utc) 
     if len(args) > 0: 
      currentdt += datetime.timedelta(*args) 
     (dt, micro) = currentdt.strftime('%Y-%m-%dT%H:%M:%S.%f').split('.') 
     tz_offset = currentdt.astimezone(tzlocal()).strftime('%z') 
     tz_offset = "Z" if tz_offset == "" else tz_offset[:3] + ":" + tz_offset[3:] 

     dt = "%s.%03d%s" % (dt, int(micro)/1000, tz_offset) 
     return dt 

    def _post(self, route, data, is_json=True,): 
     """ 
     Post Call towards Arcsight Logger 
     :param route: API endpoint to fetch 
     :param is_json: Checks if post needs to be JSON 
     :param data: Request Body 
     :return: HTTP Response 
     """ 

     if not data: 
      return 

     url = self.TARGET + route 
     if is_json: 
      return requests.post(url, json=data, verify=False) 
     else: 
      return requests.post(url, data, verify=False) 

Das funktioniert ganz gut, wenn ich manuell TARGET in diesem Skript gesetzt, aber wenn ich zu einem anderen Skript importieren, wie folgt aus:

import arcsightrest 

arcsight = arcsightrest.ArcsightLogger('admin', 'somepassword', False) 
arcsight.TARGET = 'https://10.10.10.10:9000' 
with arcsight.search('query') as search: 
    search.wait() 
    data = search.events(custom=True) 
    print data 

Dann, wenn ich laufe das Skript, sehe ich, dass TARGET nie tatsächlich überschrieben wird, weil der Traceback heißt es immer noch, dass es die alte TARGET im init Funktion dieses Aufrufs verwendet (die _POST nennt):

Traceback (most recent call last): 
    File "test.py", line 3, in <module> 
    arcsight = arcsightrest.ArcsightLogger('admin', 'somepassword', False) 
    File "/var/www/Projects2/ArcsightSDK/arcsightrest.py", line 37, in __init__ 
    }, is_json=False) 
    File "/var/www/Projects2/ArcsightSDK/arcsightrest.py", line 69, in _post 
    return requests.post(url, data, verify=False) 
    File "/usr/lib/python2.7/site-packages/requests/api.py", line 110, in post 
    return request('post', url, data=data, json=json, **kwargs) 
    File "/usr/lib/python2.7/site-packages/requests/api.py", line 56, in request 
    return session.request(method=method, url=url, **kwargs) 
    File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 475, in request 
    resp = self.send(prep, **send_kwargs) 
    File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 596, in send 
    r = adapter.send(request, **kwargs) 
    File "/usr/lib/python2.7/site-packages/requests/adapters.py", line 487, in send 
    raise ConnectionError(e, request=request) 
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='something', port=9000): Max retries exceeded with url: /core-service/rest/LoginService/login (Caused by NewConnectionError('<requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x1e59e50>: Failed to establish a new connection: [Errno -2] Name or service not known',)) 

Antwort

1

Sie überschrieben werden variable nach Erstellen es Instanz

arcsight = arcsightrest.ArcsightLogger('admin', 'somepassword', False) 
#__init__ has been already done 

arcsight.TARGET = 'https://10.10.10.10:9000' 

so in der __init__ Funktion es den alten Wert hat. Sie müssen Variablen ändern, indem Sie Klasse nicht die Instanz

import arcsightrest 

arcsightrest.ArcsightLogger.TARGET = 'https://10.10.10.10:9000' 
+0

Könnten Sie erklären, wie soll ich zu Definieren Sie diese Variable, bevor ich die Instanz erstelle? Ich habe versucht, 'arcsightrest.TARGET = 'https: //10.10.10.10: 9000'' vor der Erstellung der Instanz hinzuzufügen, aber das hat nicht geholfen. – Marius

+0

check out the edit –

+0

Das hat den Trick, ich glaube, ich habe vergessen, die Klasse auch hinzufügen, wenn Sie das Ziel definieren. Vielen Dank! – Marius

1

Da Sie ein anderes Ziel verwenden möchten für verschiedene Instanzen eine Instanz-Variable verwenden, nicht eine Klassenvariable. Schließlich ist es nicht wirklich eine Konstante, wenn es sich ändern wird.

Sie können den Wert für das URL-Ziel in der __init__()-Methode übergeben. Verwenden Sie einen Standardwert, wenn ein geeigneter ist:

class ArcsightLogger(object): 
    """ 
    Main Class to interact with Arcsight Logger REST API 
    """ 

    def __init__(self, username, password, disable_insecure_warning=False, target='https://SOMETHING:9000'): 
     self.target = target 
     # etc... 

Dann self.target in _post() verwenden.

Wenn Sie nicht wie die standardmäßig in der __init__() Methode Argument einstellen, dann können Sie einen Standardwert als Klassenvariable definieren und es verwenden, um initialisieren self.target:

class ArcsightLogger(object): 
    """ 
    Main Class to interact with Arcsight Logger REST API 
    """ 

    TARGET = 'https://SOMETHING:9000' 

    def __init__(self, username, password, disable_insecure_warning=False, target=None): 
     self.target = target if target is not None else self.TARGET 
Verwandte Themen