Trouble calling a method in an init
You cannot use self before all the stored properties have been initialised
The rule is simple and you are violating it here
self.date = getDateString()
infact this line is equivalente to
self.date = self.getDateString()
and as you can see you are using self
while date
has not been initialised yet.
You must init date
before calling the instance method getDateString()
.
A class method
If you really want to call a method to initialize date
it must be a class method
class SomeClass {
let title: String
let content: String
let date: String?
init(title: String, content: String) {
self.title = title
self.content = content
self.date = SomeClass.getDateString()
}
class func getDateString() -> String {
return "A date"
}
}
A few improvements
- If then
date
should contain... a Data then its type should be NSDate, notString
- If the
date
property should indicate the time when the value has been created then you can assign it= NSDate()
on the declaration of the property created
is a better name for this property
These 3 suggestions comes from the comment of user user3441734
.
This is the updated code
class SomeClass {
let title: String
let content: String
let created = NSDate()
init(title: String, content: String) {
self.title = title
self.content = content
}
}
Calling a class function inside of __init__
Call the function in this way:
self.parse_file()
You also need to define your parse_file()
function like this:
def parse_file(self):
The parse_file
method has to be bound to an object upon calling it (because it's not a static method). This is done by calling the function on an instance of the object, in your case the instance is self
.
Swift: why I can't call method from override init?
There are two competing initialization safety checks that are causing your problem.
Safety check 1
A designated initializer must ensure that all of the properties introduced by its class are initialized before it delegates up to a superclass initializer.
and
Safety check 4
An initializer cannot call any instance methods, read the values of any instance properties, or refer to self as a value until after the first phase of initialization is complete.
Here is how it works.
override init() {
super.init() // Fails safety check 1: uuid is not initialized.
uuid = createUUID()
}
conversely,
override init() {
uuid = createUUID() // Fails safety check 4: cannot call an instance method before initialization is complete.
super.init()
}
Thanks to @Ruben in his answer
Is it possible to init a class and call a method at the same time?
To make the call like this, some_method
must be static. That's because some_class
is missing the braces ()
which would instantiate an object. Static methods do not have a self
argument and have a @staticmethod
attribute.
If that method shall return an instance, you need to call the constructor some_class()
.
class some_class:
def __init__(self, arg_1, arg_2):
self.arg_1 = arg_1
self.arg_2 = arg_2
@staticmethod
def some_method(arg_1, arg_2):
return some_class(arg_1, arg_2)
some_object = some_class.some_method('arg_1', 'arg_2')
print(some_object)
Style note: classes should be upper case in Python.
Why calling a function inside a Python class __init__ can be both Attribute and Method?
In case 1, your constructor calls fun() which has a line inside of it to overwrite itself with an attribute value. This is confusing and not a good thing to do because it is confusing.
In case 2, your fun method does not include the line to overwrite itself so it doesn't get overwritten.
In case 3, you never actually call your fun method so it never has a chance to overwrite itself. If you called it with person_1.fun() i.e. with parentheses, then it would execute and overwrite itself and from that point on, person_1.fun would be an attribute value.
Remember that in python, a function/method ONLY executes if it is called with parentheses. If you don't express it with parentheses, then the result of evaluation is not the output of the function, but instead the expression produces a reference to the function itself, which can be put in another variable or in a data structure and called later.
To illustrate this:
>>> def my_func():
... print('got called')
... return 42
...
>>> x = my_func #no parentheses, x becomes an alias to my_func
>>> y = my_func() #parentheses means actually execute
got called
>>> y
42
>>> x
<function my_func at 0x765e8afdc0>
>>> x() #x is a reference to my_func and can be called itself
got called
42
>>>
How to call a function inside the __init__ function?
Here's the modified code:
class TemperatureFile:
def __init__(self, filename):
self.temperatureList = self.loadTemperatureData(filename) # The __init__requirement (this line). But it doesn't make sense to assign a method's return to a member, when that member could be easily set from within the method
def calculateAverage(self): # The calculateAverage requirement
if not self.temperatureList:
return None
#return sum(self.temperatureList) / len(self.temperatureList)
temp_sum = 0
for temp in self.temperatureList:
temp_sum += temp
return temp_sum / len(self.temperatureList)
def loadTemperatureData(self, filename): # The loadTemperatureData requirement (whole function)
temps = list()
with open(filename, "r") as temperartureFile:
for line in temperartureFile.readlines():
temps.append(float(line.strip()))
return temps
def main():
num1 = 35
num2 = 63
num3 = 40
temperatureFile = open("Temperatures.txt", "w")
temperatureFile.write(str(num1) + "\n")
temperatureFile.write(str(num2) + "\n")
temperatureFile.write(str(num3) + "\n")
temperatureFile.close()
Temperatures = TemperatureFile("Temperatures.txt")
print(Temperatures.calculateAverage())
main()
Notes:
- I stripped a lot of the old (unused) code
- The commented
return
line fromcalculateAverage
is the simplified form of the 4 lines below it. You can decomment it and delete the 4 following lines - In
main
, instead of havingnum1
,num2
, ... you could create a list:temperatures = [35, 63, 40]
, and then iterate over it:for temperature in temperatures:
,temperatureFile.write(str(temperature) + "\n")
. It's more elegant, and if you want to add another temperature, you just add a new element in the list
Output:
(py35x64_test) c:\Work\Dev\StackOverflow\q47102727>"c:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" a.py
46.0
How do I call a classes method from another class without initialising the first class?
SOLUTION
Thanks all for your help, I have a better understanding of it now. What I did in the end as suggested in comments was to remove these particular methods from the classes and make them global functions. I actually went through and removed all methods that weren't specifically referencing self (or made sense to leave them as class methods) and made them global. Looking at it now I think this is a better way to structure the code.
Thanks all.
Calling a method from the init method?
Respectively (I'd use list formatting but I can't make it work with blockquotes...!):
Is this the correct way to set up the headers array in an init method?
Yes, but there's no point having the array
variable, you might as well just do: headersArray = [[NSMutableArray alloc] init];
Am I allowed to call self.parentTableView
from the init
method?
No, to quote the Apple docs on Practical Memory Management:
Don’t Use Accessor Methods in Initializer Methods and dealloc
. You should access the ivar directly (as you do with headersArray
)
Am I allowed to call a method from the init
method (in this case, the prepareTags
method calls self
too. Will self
be ready to use, even though the init
method hasn't returned yet?
Yes. Just be very careful (your object may not have been fully initialised, it shouldn't use accessor methods so as to comply with the previous restriction, et cetera)
Is it bad form to call an instance method from within that instance's __init__ method?
It's fine to call instance methods within __init__
, but be careful if they might be overridden in subclasses:
class A(object):
def __init__(self):
self.greet()
def greet(self):
print('Hello from A')
class B(A):
def __init__(self, name):
super(B, self).__init__()
self.name = name
def greet(self):
print('Hello from B', self.name)
Now if B is instantiated, B.greet
is called by A.__init__
before its preconditions are satisfied (self.name
is not defined).
Related Topics
Swift - Connect Delegate to Custom Xib Cell
Why Does a Function Have Long-Term Write Access to All of Its In-Out Parameters
Convert Input Data to Integer in Swift
Swift Bug? Calling Super Class Method When Subclass with Generic Type
List Scroll Freeze on Catalyst Navigationview
Swift Auto Completion Not Working in Xcode 6 Beta
Swift: Strange Behavior About Unwrapping
Way to Check If Up or Down Button Is Pressed with Nsstepper
Swiftui Published Updates Not Refreshing
Swift Compile Error, Subclassing Nsvalue, Using Super.Init(Nonretainedobject:)
Root Class of All Classes in Swift
Compiler Segmentation Fault While Using Set in Swift
Swift: Trunc a Floating Number to Show It in a Label
Swiftui Go Back Programmatically from Representable to View
Why Is This Predicate Format Being Turned into '= Nil'
Covert Realm List to Realm Result
Create Custom Action in a Class for Use in Interface Builder