so I'm amateur programmer, and I wanted to do something with functions for a little text-based hacking game. In it, a function would be called to allow the player to find the loot and so forth. So I was doing some 'small-scale testing';
And during my testing, I found that if I had a function (which called a different function inside of it), then some text being 'printed', the second function would be called first.
#Example using a sort of 'Decorator'.
def Decor(func):
print("================")
print("Hey there")
print("================")
print("")
func
def Hello():
print("And HELLO WORLD!")
decorated = Decor(Hello())
decorated
But the output is always something along the lines of:
And HELLO WORLD!
================
Hey there
================
Is there a way to make the function be called after the text is printed?
Or simply delay the function being called.
Or am I going about this the wrong way?
Thanks for you time.
The issue here is that you are passing the result of Hello() to Decor. This means that Hello() will be processed first and then the result will be passed to Decor as parameter. What you need is something like this
def Decor(func):
print("================")
print("Hey there")
print("================")
print("")
func()
def Hello():
print("And HELLO WORLD!")
decorated = Decor(Hello)
decorated
this is one of the usual approaches to decorate a function in python:
def Decor(func):
def new_func():
print("================")
print("Hey there")
print("================")
print("")
func()
return new_func
def Hello():
print("And HELLO WORLD!")
decorated = Decor(Hello)
decorated()
this way the statements in your Decor and Hello functions are not called until you call decorated().
you could use the decorator also this way:
#Decor
def Hello():
print("And HELLO WORLD!")
Hello() # is now the decorated version.
there is a primer on decorators on realpython.com that might help.
Related
In the docs it is written, that "Any C data that you explicitly allocated (e.g. via malloc) in your __cinit__() method should be freed in your __dealloc__() method."
This is not my case. I have following extension class:
cdef class SomeClass:
cdef dict data
cdef void * u_data
def __init__(self, data_len):
self.data = {'columns': []}
if data_len > 0:
self.data.update({'data': deque(maxlen=data_len)})
else:
self.data.update({'data': []})
self.u_data = <void *>self.data
#property
def data(self):
return self.data
#data.setter
def data(self, new_val: dict):
self.data = new_val
Some c function has an access to this class and it appends some data to SomeClass().data dict. What should I write in __dealloc__, when I want to delete the instance of the SomeClass()?
Maybe something like:
def __dealloc__(self):
self.data = None
free(self.u_data)
Or there is no need to dealloc anything at all?
No you don't need to and no you shouldn't. From the documentation
You need to be careful what you do in a __dealloc__() method. By the time your __dealloc__() method is called, the object may already have been partially destroyed and may not be in a valid state as far as Python is concerned, so you should avoid invoking any Python operations which might touch the object. In particular, don’t call any other methods of the object or do anything which might cause the object to be resurrected. It’s best if you stick to just deallocating C data.
You don’t need to worry about deallocating Python attributes of your object, because that will be done for you by Cython after your __dealloc__() method returns.
You can confirm this by inspecting the C code (you need to look at the full code, not just the annotated HTML). There's an autogenerated function __pyx_tp_dealloc_9someclass_SomeClass (name may vary slightly depending on what you called your module) does a range of things including:
__pyx_pw_9someclass_9SomeClass_3__dealloc__(o);
/* some other code */
Py_CLEAR(p->data);
where the function __pyx_pw_9someclass_9SomeClass_3__dealloc__ is (a wrapper for) your user-defined __dealloc__. Py_CLEAR will ensure that data is appropriately reference-counted then set to NULL.
It's a little hard to follow because it all goes through several layers of wrappers, but you can confirm that it does what the documentation says.
I'm developing a simple window that performs some operations at closure. This is my code extract:
from javax.swing import *
from java.awt import *
from java.awt.event import *
from java.io import *
import javax.swing.table.DefaultTableModel as DefaultTableModel
class registro(JFrame):
def __init__(self):
super(registro, self).__init__()
self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
self.setExtendedState(JFrame.MAXIMIZED_BOTH)
#[...]
headers = ('Data e orario',
'Personale UO Q&A',
'Tipologia di attività'.decode('utf-8'),
'Personale incontrato con strutture di appartenenza',
'Note')
self.model = DefaultTableModel([["","","","",""]], headers)
self.table = JTable(self.model)
#[...]
self.addWindowListener(self.onClose())
#[...]
def onClose(self):
class saver(WindowAdapter):
tableModel = self.model
def windowClosing(self, event):
print tableModel #HERE IS THE ERROR!!!!!!!!!
return saver()
The error reported on the highlighted line is the following:
NameError: global name 'tableModel' is not defined
Although I have declared the variable inside the listener (to avoid misunderstanding between the two self), I don't understand why it has never been recognized. I'm almost a novice with object-oriented programming and Swing windows on Jython, and I hope this is not my (very) serious shortcoming!
Many thanks in advance.
There's a fairly subtle scope issue here, which is mostly about Python syntax, but also about what code you want to have access to the tableModel. The tableModel variable is not visible by default because you are inside the onClose() function. A defensive solution to this is to explicitly pass the needed variable into the new saver object. I personally prefer this as it more explicitly declares the inputs for saver objects.
class WindowAdapter:
None
class App:
def __init__(self):
self.model = 'DUMMYMODEL'
def onClose(self):
class Saver(WindowAdapter):
def __init__(self,tableModel):
WindowAdapter.__init__(self)
self.tableModel = tableModel
def windowClosing(self,event):
print (self.tableModel)
return Saver(self.model)
if __name__ == '__main__':
app = App()
sv = app.onClose()
sv.windowClosing(event=None)
(This code is cut down and in pure Python to show it is largely scoping related.)
An alternative would be using the Python global keyword to expose the tableModel variable to all lower scopes.
class WindowAdapter:
None
class App:
def __init__(self):
self.model = 'DUMMYMODEL'
def onClose(self):
global tableModel
tableModel = self.model
class Saver(WindowAdapter):
def windowClosing(self,event):
print (tableModel)
return Saver()
if __name__ == '__main__':
app = App()
sv = app.onClose()
sv.windowClosing(event=None)
I'm brand new to Python and come from a C/C++ background. I'm looking for a way to differentiate function calls based on the data that is being passed.
An example:
class RomanNumeral():
def __init__( self, value ):
# Assign stuff
Now, let's say I'd like to be able to initialize an instance of RomanNumeral with either an int or a string (e.g., 11 or XI). How is this handled in Python?
I'm essentially looking for this C++ equivalent:
RomanNumeral();
RomanNumeral(int value);
RomanNumeral(string value);
Do I have to throw a try block around some code and catch ValueError if I'm given a string?
Python does not complain about type mismatch like C++. Syntactically, you can assign any data type to any variable. For your case,
class RomanNumeral:
def __init__(self, value):
self.value = value
And in any method you use it, you can:
def some_method(self):
if isinstance(self.value, int):
print "Value is a number"
elif isinstance(self.value, str):
print "Value is a Roman Number"
This is a simple way to handle types in Python
I'm trying to call a different function inside the same class from my main function and I can seem to figure where the error is.
I keep getting this error relating to functions not being defined and I'm not sure how to resolve it:
NameError: global name 'results' is not defined
class Darts:
def main() :
print results()
def results() :
round_result_totals = "Stuff"
return round_result_totals
#RUNNING CODE
main()
Make sure that you define properly self in your functions and initialize an object first before you do anything else. You can't just call a function from a class without creating an instance of that class and calling a function from that instance (NOT THE CLASS). Usually you want to have an __init__ in your python classes.
class Darts:
def __init__(self):
pass
def main(self):
print(self.results())
def results(self):
round_result_totals = "Stuff"
return round_result_totals
Dart1 = Darts()
Dart1.main()
If you want to use variables, self is critical too for encapsulation.
class Darts:
def __init__(self):
self.a = 500
def main(self):
self.a += 1
print(self.a)
Dart1 = Darts()
Dart1.main()
You need to pass self (the instance of your object) into your object's methods.
class Darts:
def main(self) :
print self.results()
def results(self) :
round_result_totals = "Stuff"
return round_result_totals
You're missing all of the required references to self inside your class. It should look like this:
class Darts:
def main(self) :
print self.results()
def results(self) :
round_result_totals = "Stuff"
return round_result_totals
Here is the Python documentation on classes. And the fifth paragraph of this section makes reference to the convention of self.
Briefly: the first argument to a method of a Python class is automatically passed in a reference to the instance of that class from which the method is being called (provided it is being called as an instance method). This is done automatically by Python's interpreter. This parameter still needs to be explicitly stated in the method definition, however, and the convention is to call it self.
I have several functions such as
def plot_lines(...):
def plot_setup():
def BP4_avg(...):
which all work fine but when I add a calling function main() it breaks
def main():
...
plot_setup()
BP4_avg(...)
plt.show()
if __name__ == "__main__":
main()
Any ideas?
If I remove main() and just have
plot_setup()
BP4_avg(...)
plt.show()
program works.
Thanks
In the first version you're just defining the functions but you are not calling them - so everything works fine.
On the second version (the one with main() ) you are actually executing these functions and one of them breaks...