So I wrote a function called 'anonimize' that gets a string and returns that string with some details blacked-out, using regex. The function works fine on its own, but I tried to turn it into a decorator and things went south and got so many crashes so many times. I am learning decorators and would really like to understand what I am doing wrong. In this unsuccessful version I got "TypeError: BankApplication.anonimize() missing 1 required positional argument: 'callable'".
import re
class BankApplication:
def __init__(self, bank_name):
self.name = bank_name
'''
Perform anonimization to the text data:
1. Remove possible account numbers (more than 5 digits in a row)
2. Remove possible email addresses
3. Remove possible First Last names (two consequtive words
starting from upper case, but not divided by .)
'''
def anonimize(func):
def inner(arg):
ret = func(arg)
print(
re.sub("[A-Z][a-z] \s[A-Z][a-z] ", "***", re.sub("\S @\S \.\S ", "***", re.sub("\d{5,}", "***", arg))))
return ret
return inner
@anonimize
def feedback(self, feedback_text):
print("Called feedback")
@anonimize
def log_info(self, info_to_log):
print("Called feedback")
bank = BankApplication("Bank")
bank.feedback("Name: John Doe\nE-mail: [email protected]\nAccount number: 911911911.")
CodePudding user response:
You need to move anonimize
out of the class. Why?
The first argument that gets passed to a standard method is always the owning object itself (the self
argument is the standard syntax, but you can call it anything).
You cannot use it as a static method because decorators are run when the code is defined. You won't be able to reference the owning object because it won't have been instantiated yet.
import re
def anonimize(func):
def inner(arg):
ret = func(arg)
print(
re.sub("[A-Z][a-z] \s[A-Z][a-z] ", "***", re.sub("\S @\S \.\S ", "***", re.sub("\d{5,}", "***", arg))))
return ret
return inner
class BankApplication:
def __init__(self, bank_name):
self.name = bank_name
'''
Perform anonimization to the text data:
1. Remove possible account numbers (more than 5 digits in a row)
2. Remove possible email addresses
3. Remove possible First Last names (two consequtive words
starting from upper case, but not divided by .)
'''
...
CodePudding user response:
anonimize
shouldn't be an instance method of BankApplication
, it doesn't even accept self
. Define it outside of the class.
EDIT: I've also suggested @staticmethod
, but it wouldn't work either, see @James's answer.
CodePudding user response:
Ok, so this was the wrong version I posted:
def anonimize(func):
def inner(text):
print(re.sub("[A-Z][a-z] \s[A-Z][a-z] ", "***", re.sub("\S @\S \.\S ", "***", re.sub("\d{5,}", "***", text))))
return func(text)
return inner
And this is the way it should have been:
def anonimize(func):
def inner(self, text):
text = re.sub("[A-Z][a-z] \s[A-Z][a-z] ", "***", re.sub("\S @\S \.\S ", "***", re.sub("\d{5,}", "***", text)))
return func(self, text)
return inner