Since these are member functions, call it as a member function on the instance, self.
def isNear(self, p):
self.distToPoint(p)
...
Answer from Jeff Mercado on Stack OverflowSince these are member functions, call it as a member function on the instance, self.
def isNear(self, p):
self.distToPoint(p)
...
That doesn't work because distToPoint is inside your class, so you need to prefix it with the classname if you want to refer to it, like this: classname.distToPoint(self, p). You shouldn't do it like that, though. A better way to do it is to refer to the method directly through the class instance (which is the first argument of a class method), like so: self.distToPoint(p).
In this case, I think using different classes is probably the way to go.
from abc import ABC, abstractmethod
class Returns(ABC):
def __init__(self, stock_ticker):
self.stock_ticker = stock_ticker
def get_price_data_from_ticker(self):
pass # FIXME: implement getting stuff from the data source here
@abstractmethod
def calculate_returns(self, prices):
pass
def get_returns(self):
return self.calculate_returns(self.get_price_data_from_ticker())
class ArithmeticReturns(Returns):
def calculate_returns(self, prices):
return [prices(i) - prices(i - 1) for i in prices]
class LogarithmicReturns(Returns):
def calculate_returns(self, prices):
return [np.ln(prices(i) / prices(i - 1)) for i in prices]
x = LogarithmicReturns('AAPL US Equity')
print(x.get_returns())
Concepts used:
- Abstract Base Classes:
Returnsis now a class that cannot be substantiated, only subclasses that implement all abstract methods can. This means both subclasses implement the same interface without having to do all of the heavy lifting themselves. List comprehensions:
l = [a + 1 for a in exp]is equivalent tol = [] for a in exp: l.append(a + 1)- Separation of concerns:
calculate_returnsis now no longer concerned with how data is collected from the ticker, it purely calculates the returns based on the prices given to it.
Your code contained syntax errors in arithmetic and logarithmic in the loops, so you will need to fix that. If prices is a list, I would use something like [current_price - previous_price for current_price, previous_price in zip(prices[1:], prices)], but I decided to leave it as is in case prices is actually a strange iterable that iterates over the indexes and is indexed by calling.
I think you're on the right way; but using some dependency injection might work better in your case. You could do something like this:
def arithmetic(prices):
daily_ret = []
for i rows in prices:
returns.append(prices(i)-prices(i-1))
return daily_ret
def logarithmic(prices):
daily_ret = []
for i rows in prices:
returns.append(np.ln(prices(i) / prices(i-1))
return daily_ret
class Returns:
def __init__(self, stock_ticker, return_calc=arithmetic):
self.stock_ticker = stock_ticker
self.return_calc = return_calc
def calculate_returns(self):
get_price_data_from_ticker = whatever_data_source()
return self.return_calc(get_price_data_from_ticker)
x = Returns('AAPL US Equity', return_calc=logarithmic)
print(x.calculate_returns())
by directly passing the function instead of passing a string constant to identify which function to use.
By the way, this is what you were doing in this line:
def __init__(self, stock_ticker, return_calc=arithmetic):
which means that the default value that you are passing right now isn't a string, but directly the function
python - How can I call a function inside a class? - Stack Overflow
python - Call function from one class in the same class - Data Science Stack Exchange
python - How to call a function from an object within a class? - Stack Overflow
python - How to call function defined inside a class? - Stack Overflow
I'm learning to work with classes and I'm trying to turn my procedural code that's working perfectly into a class with a series of functions (def) within. I ran into an error while testing though. It says "name def2 is not defined," and I'm not sure how to define it.
I wrote:
from <file> import Class x = Class() x.def1() x.df
So far it works perfectly and the data table looks like what I expect. def1 only uses self as a parameter.
After def1, def2-4 all use different parameters, so I can't simply write x.def2 like I did above, otherwise it errors out because I didn't input a second parameter.
Then def5 is another function with only self as a parameter that is merely a series of procedural lines that call upon def2-4 written above. However, when I tried to run x.def5(), it errors out saying "def2 is not defined," and if I comment out the def2 part, it errors out saying "def3 is not defined" instead.
How do I define these functions so I can call upon them in a separate function within the same class?
When calling member functions you have to use the self argument, and initiate the class. So the calls would be like this.
class fg():
def red(self, text):
return f'\033[00;49;031m{text}\033[0m'
def heading(self, text):
return self.red(text)
and then
print(fg().red("My text"))
# prints as expected
# Command 2:
print(fg().heading("My text"))
First, there is a typo in your code. You misspelled return as "retrun". Also, you can't call a class method directly. Here is what you're probably looking for.
class fg():
def __init__(self, text):
self.text = text
def red(self):
return f'\033[00;49;031m{self.text}\033[0m'
def heading(self):
return self.red()
And now you can import the file.
from globals import fg
obj = fg("My text")
print(obj.red())
print(obj.heading())
I have made a lot of modifications to your code.
- Use self to call the class methods
- If the text parameter is the same for both, you need not pass it every time you call these methods. Instead, you can initialize that in the self method itself.
- You first need to create an object of a class to access its methods (called constructors).
Using self.mode_impute is indeed the correct way of calling the function inside the class. However the issue here is that your call is not part of a function, putting the for loop with the call inside a function (e.g. __init__) should solve the error as self is defined within the function (passed as the first argument).
You can move the for loop calling the model_impute() method either to within your __init__() constructor or outside of the impute class. But I donโt see the dataset df6 defined anywhere.
So I would redesign things a bit. Create a fit_transform(X) method within your impute class. This takes in a X data frame from the user, saves it for the class instance & then populates missing values with the for loop invoking mode_impute().
You misunderstand how classes work. You put your call inside the class definition body; there is no instance at that time, there is no self.
Call the method on the instance:
instance = printclass()
instance.dotheprint()
Now the dotheprint() method is bound, there is an instance for self to refer to.
If you need dotheprint() to be called when you create an instance, give the class an __init__ method. This method (the initializer) is called whenever you create an instance:
class printclass():
string="yes"
def __init__(self):
self.dotheprint()
def dotheprint(self):
print self.string
printclass()
You really need to understand Object-Oriented Programming and its implementation in Python. You cannot "call" a class like any function. You have to create an instance, which has a lifetime and methods linked to it:
o = printclass() # new object printclass
o.dotheprint() #
A better implementation of your class:
class printclass():
string="yes" #beware, this is instance-independant (except if modified later on)
def dotheprint(self):
print self.string
def __init__(self): # it's an initializer, a method called right after the constructor
self.dotheprint()
You cannot. The function is part of the class, so to access it you must access the class first.
class myClass:
def foo(self):
# do something
myClass().foo()
If you just don't want to type myClass().foo() but only foo then you could just return the myClass() in a new function called foo():
def foo():
return myClass().foo()
You can use self in a class when calling from inside the class itself:
class myClass:
def __init__(self):
pass
def foo(self):
pass
def method2(self):
self.foo()
This does not create a new instance of myClass like calling myClass().foo() would, and you do not need to pass the same arguments that you may have passed in myClass.
Since foo() has a self parameter, that means it is an instance method, and therefore it is only callable from an instance of myClass.
If you want foo to be callable without an instance, use the @staticmethod decorator, and remove self from the parameter list.
You have to initialize the class, then only you can call the methods of that class. Also, methods should have it's first argument as self.
class H:
def y(self):
print "j"
g = H()
g.y()
Refer here for more details about self.
You should definitely check this chapter for class.
You've got answers and comments, so let me explain the error message.
In your code, g and H are different names for the same thing, so the two errors are one.
Now, H is an (old-style) class and all the functions def'ed below it, unless "processed" with tricks like classmethod or staticmethod, are methods. When you access the methods as attributes of the class H, they're known as "unbound" methods because they're not yet bound to an instance of the class H.
To understand how Python's core model of classes, methods, and attributes, I recommend the excellent posts by Shalabh Chaturvedi:
- Python Types and Objects
- Python Attributes and Methods
The tl;dr version: normally you're expected to call a method by invoking an instance's bound method:
>>> class H(...):
>>> def y(...):
>>> h_instance = H()
>>> h_instance.y(...)
Python will put that instance (h_instance here in the fake code snippet) as the first argument to the method. If you call it as h_instance.y(), the actual argument list is (h_instance); if you call it as h_instance.y(a), the arguments are (h_instance, a).
This is why you almost invariably find the first formal argument in a method definition to be self. There's nothing special about this name, except that Python expects that slot be reserved for the instance on which the method is invoked. It allows you to define the method with an empty argument list, but that one wouldn't be useful when you actually use the instance. In that case you'll always get TypeError -- because the call sends ONE argument (the "self" instance) while there's none in the method definition.
As a demonstration, consider the following session:
In [1]: class H(object): # New-style class, doesn't matter here.
...: def y(self): # Notice the call signature: "self" included
...: print "j"
In [2]: h_instance = H() # Create an instance from the class
# This is how normally you're expected to call. There's no argument
# passed to the *bound* to the instance h_instance, because when you do
# this Python will carry out the syntactic desugaring and call on the
# instance.
In [3]: h_instance.y()
j
# This does the same thing and demonstrates the concept of an
# unbound method. It's not bound to any specific instance of H, so
# you'll have to specify which instance to call.
In [4]: H.y(h_instance)
j