1

Here is definition of my class full of static functions. I want to use all of them in "sendLog" function which call himself with time interval (10 sec here). When I run this interpreter tells me "TypeError: sendLog() takes at least 5 arguments (0 given)" But it if I enter the same params I will need to define sendLog again and again because it calls himself repeatly.. I know its not the way But cant figure it out.

class AccessLog:

@staticmethod
def backupAccessLog(target, source):
    newfile = os.path.splitext(source)[0] + "_" + time.strftime("%Y%m%d-%H%M%S") + os.path.splitext(source)[1]
    copyfile(source,newfile)
    shutil.move(newfile,target)

@staticmethod
def emptyAccessLog(filename):
    open(filename, 'w').close()

@staticmethod
def postLogstoElastic():
    fileLogs = open("example.log", "rw+")
    fileBackups = open("logs_of_accesslog.log","rw+")
    lines = fileLogs.read().splitlines()
    logging.basicConfig(format='%(asctime)s>>>%(message)s',filename='logs_exceptions.log',level=logging.DEBUG)
    es = Elasticsearch(['http://localhost:9200/'], verify_certs=True)
    #es.create(index="index_log23June", doc_type="type_log23June")
    es.indices.create(index='index_log23June', ignore=400)
    i=0
    for item in lines:
        try:
            i+=1
            if bool(item):
                es.index(index="index_log23June",doc_type="type_log23June", body={"Log":item})
            else:
                print "a speace line ignored. at line number:", i
                raise ValueError('Error occurred on this line: ', i)
            print "lines[",i,"]:",item,"\n"

        except ValueError as err:
            logging.error(err.args)

@staticmethod
def sendLog(interval, worker_functions, iterations=1):
    def call_worker_functions():
        for f in worker_functions:
            f() #ERROR: Msg: 'NoneType' object is not callable
    for i in range(iterations):
        threading.Timer(interval * i, call_worker_functions).start()

and I want to call this method with this line:

try:
    AccessLog.AccessLog.sendLog(
    interval=10,
    worker_functions=(
        AccessLog.AccessLog.backupAccessLog("logbackups","example.log"),
        AccessLog.AccessLog.emptyAccessLog("example.log"),
        AccessLog.AccessLog.postLogstoElastic()
    ),
    iterations=999
)
except ValueError as err:
    logging.error(err.args)

"TypeError: sendLog() takes at least 5 arguments (0 given)" It looks normal but How can I handle this ?

5
  • 1
    Can you post the full traceback please so we know what line the indentation error occurs? and what line that is in your code. Also why are you using semi-colons? these are completely unnecessary in Python Commented Jun 23, 2015 at 11:29
  • 1
    Also, you're using Python, not a POS language. Stop ending your lines with semicolons - they're useless noise. Commented Jun 23, 2015 at 11:32
  • 1
    indent your decorator at the same level as the function. Commented Jun 23, 2015 at 11:32
  • @ArtOfWarfare I did it even this makes better something for me :) Thank you but not the main problem :( Commented Jun 23, 2015 at 11:50
  • @MehmetYenerYILMAZ Maybe if you could update your question to contain as little code as possible? Could you re-create the same issue with only one method in a class, and without django involved? Commented Jun 23, 2015 at 11:57

2 Answers 2

2

Have you tried to set the @staticmethod on the same level as the function?

Sign up to request clarification or add additional context in comments.

5 Comments

A decorator has to have the same indentation as the function it's decorating. In the code example this is not the case. This should be flagged up by a good editor.
But maybe this is his problem.
That's definitely the problem.
do you get the same error if they are on the same level?
yes, they are same already. How can I pass this function itself as parameter actually this is my question here :)
1

Apparently you want sendLog() to call the worker functions every 10 seconds or so. Here's an easy way to do that:

class AccessLog:
    @staticmethod
    def sendLog(interval, worker_functions, iterations=1):
        def call_worker_functions():
            for f in worker_functions:
                f(*worker_functions[f])
        for i in range(iterations):
            threading.Timer(interval * i, call_worker_functions).start()

And now use it like this:

AccessLog.AccessLog.sendLog(
    interval=10,
    worker_functions={
        AccessLog.AccessLog.backupAccessLog: ("logbackups", "example.log"),
        AccessLog.AccessLog.emptyAccessLog: ("example.log",),
        AccessLog.AccessLog.postLogstoElastic: ()
    ),
    iterations=999
)

And this is just one of many many ways, but there's no need to pass the function as its own argument like you did.

3 Comments

Okey I will go in this.
I edit the question and there is an error line called f() that in for loop with "'NoneType' object is not callable" message... why it reqires type although all of them is static
@MehmetYenerYILMAZ Try the updated version; you must pass functions to the sendLog() function, we were passing function calls (= their return values)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.