how to use a Python function with keyword "self" in arguments - python

i have a function that retrieve a list of stores in Python this functions is called :
class LeclercScraper(BaseScraper):
"""
This class allows scraping of Leclerc Drive website. It is the entry point for dataretrieval.
"""
def __init__(self):
LeclercDatabaseHelper = LeclercParser
super(LeclercScraper, self).__init__('http://www.leclercdrive.fr/', LeclercCrawler, LeclercParser, LeclercDatabaseHelper)
def get_list_stores(self, code):
"""
This method gets a list of stores given an area code
Input :
- code (string): from '01' to '95'
Output :
- stores :
[{
'name': '...',
'url'
}]
"""
when i try to write get_list_stores(92) i get this error :
get_list_stores(92)
TypeError: get_list_stores() takes exactly 2 arguments (1 given)
how can you help me with this ?

If the function is inside a class (a method), write it like this:
def get_list_stores(self, code):
And you have to call it over an instance of the class:
ls = LeclercScraper()
ls.get_list_stores(92)
If it's outside a class, write it without the self parameter:
def get_list_stores(code):
Now it can be called as a normal function (notice that we're not calling the function over an instance, and it's no longer a method):
get_list_stores(92)

You don't use "self" arbitrarily - self is recommended to be the first parameter to functions which are written to be methods in classes. In that case, when it is invoked as a method, like in
class A(object):
def get_list_stores(self, code):
...
a = A()
a.get_listscores(92)
Python will insert the "self" parameter automatically on the call
(and it will be the object named "a" in the outer scope)
Outside of class definitions, having a first parameter named "self" does not make
much sense - although, as it is not a keyword it is not an error per se.
In your case, most likely,t he function you are trying to call is defined in class:
you have to call it as an attribute of an instance of the class, and then you
simply omit the first parameter - just like in the example above.

If you are trying to use it in the class, access it like this:
self.get_listscores(92)
If you are trying to access it outside of the class, you need to first create an instance of LeclercScraper:
x = LeclercScraper()
y = x.get_listscores(92)
Also, self is not a keyword. It is simply the name chosen by convention to represent a class instance within itself.
Here's a good reference:
What is the purpose of self?

Related

python class method, Looks like the wrong syntax

Sample Code:
class Mysterious:
def fake_staic():
print('fake staic')
def fake_sta_parameters(self):
print(f"fake_sta_parameters {self}")
Mysterious.fake_sta_parameters("fbc")
# output fake_sta_parameters fbc
Mysterious.fake_staic()
# output fake staic
Please define code as follows. Why can it be executed normally? Please help me explain, thanks
def fake_staic():
print('fake staic')
this function does not have self as argument and is call with class name, hence it will be treated as class method, or static method.
Whereas in second function,
def fake_sta_parameters(self):
print(f"fake_sta_parameters {self}")
you are providing it self argument, but calling it using class, and passing a value as its argument, hence self here is treated as argument and replaced with "fbc".
If you try calling this fake_sta_parameters() using object of your class, then it will give insufficient arguments error, as when a function called using object of the class, will always consider/expect function's first argument to be self reference, and hence above function will throw error as it wont have sufficient arguments to receive 'fbc' value.

How to dynamically change a method arguments in Python

Is it possible to dynamically add arguments to a Python method definition ?
I'm currently working on this piece of code:
def method(self):
pass
method.__name__ = "print"
and I want to know if it's possible to change the method's definition dynamically, like i'm changing it's name, and for example add a string argument ?

What is the use of class attribute which is a method/function

In Python when we define class all its members including variables and methods also becomes attributes of that class. In following example MyClass1.a and MyClass1.mydef1 are attributes of class MyClass1.
class MyClass1:
a = 10
def mydef1(self):
return 0
ins1 = MyClass1() # create instance
print(MyClass1.a) # access class attribute which is class variable
print(MyClass1.mydef1) # No idea what to do with it so just printing
print(ins1.mydef1) # No idea what to do with it so just printing
Output
10
<function MyClass1.mydef1 at 0x0000000002122EA0>
<bound method MyClass1.mydef1 of <__main__.MyClass1 object at 0x000000000212D0F0>>
Here attribute a is a variable and it can be used like any other variable.
But mydef1 is a method, if it is not invoked and just used like MyClass1.mydef1 or ins1.mydef1, it returns object for that method(correct me if I am wrong).
So my question is, what can we do with the Class/instance methods without invoking it? Are there any use cases for it or is it just good to know thing?
An attribute of a class that happens to be a function becomes a method for instances or that class:
inst.foo(params, ...)
is internally translated into:
cls.foo(inst, params, ...)
That means that what is actually invoked is the attribute from the class of the instance, and the instance itself is prepended to the argument list. It is just Python syntax to invoke methods on objects.
In your example the correct uses would be:
print(MyClass1.mydef1(ins1)) # prints 0
print(ins1.mydef1()) # also prints 0
Well instance methods can be called with the appropriate parameters of course:
print(ins1.mydef1()) # no parameters, so empty parenthesis, this call should print "0" in your example instead of the method description
If you use it without the parenthesis, you are playing with reference to the function, I don't think you can have any use of it, except checking the list of methods available in a class or something like that.

Python OOP init

class Sequence:
TranscriptionTable = {
"A":"U",
"T":"A",
"C":"G",
"G":"C"
}
def __init__(self, seqstring):
self.seqstring = seqstring.upper()
def transcription(self):
tt = ""
for x in self.seqstring:
if x in 'ATGC':
tt += self.TranscriptionTable[x]
return tt
DangerousVirus = Sequence('atggagagccttgttcttggtgtcaa')
print(DangerousVirus.transcription())
Hi,
I just want some clarification as to how data flows through a class. For instance, is the data in () in DangerousVirus = Sequence('atggagagccttgttcttggtgtcaa') self or seqstring?
I'm confused as to how init can have 2 variables when theres only 1 in the (). Wouldnt that mean that only self contains the sequence and seqstring is empty?
Thanks for the help! (:
self is a reference to a Sequence which is being initialized. The data string is passed as seqstring. You can see this by adding a line to print it:
print(seqstring)
The __init__ method does indeed take two arguments, but once an instance is created the self argument is "bound" to the instance (__init__ becomes a so called bound method of the instance), so you don't have to specify the instance itself anymore. If you call the unbound __init__ function from the class like this
Sequence.__init__(instance, seqstring)
you indeed have to specify the instance explicitly. The name self is just a convention, it could be anything in the definition. Take a look at the tutorial section on instance methods where this is explained.
As the other answers have said, the self arg gets passed automatically to method calls. So you must include it as the first arg in the method definition, but you must not include it in the method call.
However, there's no need to define a class for this, a simple function is sufficient. And you can use the built-in str.translate method to perform the transcription very efficiently. For large sequences, this is much faster than doing it with a Python loop as in your transcription method, since most of the work is done by compiled code, so it runs as fast as if it were written in C, not Python.
trans_table = str.maketrans('ATCG', 'UAGC')
def transcribe(seq):
seq = seq.upper()
return seq.translate(trans_table)
seq = 'atggagagccttgttcttggtgtcaa'
print(transcribe(seq))
output
UACCUCUCGGAACAAGAACCACAGUU
As mentioned in the docs, any chars that aren't in the translation table will remain unchanged in the output string. Eg,
print('abcdABCD'.translate(trans_table))
output
abcdUBGD

Interesting 'takes exactly 1 argument (2 given)' Python error

For the error:
TypeError: takes exactly 1 argument (2 given)
With the following class method:
def extractAll(tag):
...
and calling it:
e.extractAll("th")
The error seems very odd when I'm giving it 1 argument, the method should take only 1 argument, but it's saying I'm not giving it 1 argument....I know the problem can be fixed by adding self into the method prototype but I wanted to know the reasoning behind the error.
Am I getting it because the act of calling it via e.extractAll("th") also passes in self as an argument? And if so, by removing the self in the call, would I be making it some kind of class method that can be called like Extractor.extractAll("th")?
The call
e.extractAll("th")
for a regular method extractAll() is indeed equivalent to
Extractor.extractAll(e, "th")
These two calls are treated the same in all regards, including the error messages you get.
If you don't need to pass the instance to a method, you can use a staticmethod:
#staticmethod
def extractAll(tag):
...
which can be called as e.extractAll("th"). But I wonder why this is a method on a class at all if you don't need to access any instance.
If a non-static method is member of a class, you have to define it like that:
def Method(self, atributes..)
So, I suppose your 'e' is instance of some class with implemented method that tries to execute and has too much arguments.
Am I getting it because the act of calling it via e.extractAll("th") also passes in self as an argument?
Yes, that's precisely it. If you like, the first parameter is the object name, e that you are calling it with.
And if so, by removing the self in the call, would I be making it some kind of class method that can be called like Extractor.extractAll("th")?
Not quite. A classmethod needs the #classmethod decorator, and that accepts the class as the first paramater (usually referenced as cls). The only sort of method that is given no automatic parameter at all is known as a staticmethod, and that again needs a decorator (unsurprisingly, it's #staticmethod). A classmethod is used when it's an operation that needs to refer to the class itself: perhaps instantiating objects of the class; a staticmethod is used when the code belongs in the class logically, but requires no access to class or instance.
But yes, both staticmethods and classmethods can be called by referencing the classname as you describe: Extractor.extractAll("th").
Yes, when you invoke e.extractAll(foo), Python munges that into extractAll(e, foo).
From http://docs.python.org/tutorial/classes.html
the special thing about methods is
that the object is passed as the first
argument of the function. In our
example, the call x.f() is exactly
equivalent to MyClass.f(x). In
general, calling a method with a list
of n arguments is equivalent to
calling the corresponding function
with an argument list that is created
by inserting the method’s object
before the first argument.
Emphasis added.
Summary (Some examples of how to define methods in classes in python)
#!/usr/bin/env python # (if running from bash)
class Class1(object):
def A(self, arg1):
print arg1
# this method requires an instance of Class1
# can access self.variable_name, and other methods in Class1
#classmethod
def B(cls, arg1):
cls.C(arg1)
# can access methods B and C in Class1
#staticmethod
def C(arg1):
print arg1
# can access methods B and C in Class1
# (i.e. via Class1.B(...) and Class1.C(...))
Example
my_obj=Class1()
my_obj.A("1")
# Class1.A("2") # TypeError: method A() must be called with Class1 instance
my_obj.B("3")
Class1.B("4")
my_obj.C("5")
Class1.C("6")`
try using:
def extractAll(self,tag):
attention to self

Categories