How to use static method's generated output in other methods? - python

I don't understand how I am supposed to create static method, which will be run and called only once and which generates some output which will be used be other methods. For example:
class Player():
#staticmethod
def generateCardDeck():
deck = someCalculations
def someOtherMethod(self):
something = deck
def main():
Player.generateCardDeck()
if __name__ == '__main__':
main()
Is not going to work, I get error: NameError: global name 'deck' is not defined. But if I don't use static method, then how do I create multiple instances of the class, without running that method more than once (considering that other class methods would call generatedDeck() method)?

you can return the deck and use it wherever you want ... or you could make it a classmethod instead
class Player():
#classmethod
def generateCardDeck(cls):
cls.deck = someCalculations
Player.generateCardDeck()
print Player.deck
I suppose you could do roughly the same with static method
class Player():
#staticmethod
def generateCardDeck():
Player.deck = someCalculations
Player.generateCardDeck()
print Player.deck

Related

python call all functions with name patterns or other signature

I'm writing a feature generation class that can be extendable. For example in the following example any method that starts with generate is a feature generation method:
class FeatureGenerator:
def __init__(self):
self.generate_a()
self.generate_b()
def method_a(self): pass
def generate_a(self): do stuffs
def generate_b(self): do stuffs
I want to execute all methods with generate prefix within init. However, I don't want to add it manually every time I write a new method. One solution could be writing a decorator that will add it to a list and then execute all elements in the list within init. But I am not sure that's a good idea. Is there any pythonic way to do that?
Using the dir of the instance:
class FeatureGenerator:
def __init__(self):
for name in dir(self):
attr = getattr(self, name)
if callable(attr) and name.startswith("generate"):
attr()
def method_a(self): pass
def generate_a(self): print("gen a")
def generate_b(self): print("gen b")

Calling a class function from the same file in Python

How do I call a function defined in a class in Python?
import pypyodbc as pyodbc
Master_Conn = 'Driver={SQL Server};Server=server\23;Database=DBname;UID=username;PWD=password;'
Master_db = pyodbc.connect(Master_Conn)
Master_Cursor = Master_db.cursor()
class Test:
def __init__(self):
self.master_status = ""
def Getmodel(self):
self.master_status= dict(Master_Cursor.execute("select col1,col2 from tablename ").fetchall())
print (self.master_status)
Test.Getmodel()
With above code, I get
TypeError: Getmodel() missing 1 required positional argument: 'self'
So I tried Test.Getmodel(self) and it resulted in
NameError: name 'self' is not defined.
I even tried both scenarios with if __name__== '__main__': but got same errors.
You are defining Getmodel as an instance method. So it have to be called on an instance of the class Test.
To create an instance of class Test you can write
instance_of_test = Test()
Now you can call Getmodel on instance_of_test
instance_of_test.Getmodel()
You can shorten this process by writing
Test().Getmodel()
Note that self is (usually) passed hiddenly when calling an instance method; it represents the instance calling the method.
Consider the following class Pizza
class Pizza:
def __init__(self, size):
self.size = size
def get_size(self):
return self.size
First you need to create an instance of Pizza
mypizza = Pizza(42)
then you can call the instance method get_size on mypizza
mypizza.get_size()
What your doing will work if you instantiate an object of the class Test first. Instantiation just means you call the class as if it were a method which. The following should work:
Test().Getmodel()
The () is what makes the instantiation happen so now the self essentially gets passed to the Getmodel() method because an object of the class Test now exists.

how to start or call a function from a different class in python?

hey guys need to know as of how to start a method in a classA from class B
have
classA(object):
def __init__(self):
#this is where the ClassB method'' def multiplyPeople() ''should be called or started.
classB(object):
def multiplyPeople(self):
its giving an error
TypeError: unbound method multiplyPeople() must be called
with classB instance as first argument (got nothing instead)
know this is something basic, but am trying to figure out what exactly is supposed to be done and where am I getting lost.
I have called it as
classA(object):
def__init__(self):
self.PeopleVariable=classB.multiplyPeople()
It depends on how you want the function to work. Do you just want to use the class as a placeholder? Then you can use a so called static method for which you do not need to instantiate an object.
Or you can use a regular method and use it on a created object (notice that there you have access to self)
class A():
def __init__(self):
b = B()
b.non_static()
B.multiplyPeople()
class B():
#staticmethod
def multiplyPeople():
print "this was called"
def non_static(self):
print self, " was called"
if __name__ == "__main__":
a = A()
output:
<__main__.B instance at 0x7f3d2ab5d710> was called
this was called

Python - how can I get the class name from within a class method - using #classmethod

I have the following code:
class ObjectOne(object):
#classmethod
def print_class_name(cls):
print cls.__class__.__name__
def print_class_name_again(self):
print self.__class__.__name__
if __name__ == '__main__':
obj_one = ObjectOne()
obj_one.print_class_name()
obj_one.print_class_name_again()
The output is:
type
ObjectOne
I would like the output to be:
ObjectOne
ObjectOne
But I would like to keep test_cls as a class method via the #classmethod decorator.
How can I accomplish this?
A classmethod receives the class as its argument. That's why you're calling it cls. Just do cls.__name__.
It's cls.__name__. cls already points to the class, and now you're getting the name of its class (which is always type).
I had a similar question and wantend to get the class name for logging and the function/method name.
__name__ : gives the program name
__class__.__name__ gives the class name
inspect.stack()[0][3] gives the module name. (you have to import inspect).
Cheers

Error: "x instance has no attribute y" when trying to inherit from class

I can't really understand what I'm doing wrong, since when I try it in "small scale" and it is working there.
I have a class named Play()
I goes like this:
class Play():
def __init__(self):
file = open("/home/trufa/Desktop/test", "r")
self.word = random.choice(file.readlines()).rstrip()
self.errAllowed = 7
self.errMade = 0
self.errList = []
self.cheatsAllowed = 2##chetas not incrementing
self.cheatsMade =0
self.wordList = ["*"]*len(self.word) ##this one is the one I want to have available in another class
...
Then I have another class called Score()
class Score(Play):
def __init__(self):
self.initialScore = 0
def letterGuess(self):
self.initialScore += 1
return self.errList
...
I instantiated both:
game = Play()
points = Score()
And if I do:
print points.letterGuess()
It gives me an error:
Traceback (most recent call last):
File "/home/trufa/workspace/hangpy/src/v2.py", line 188, in <module>
startGame()
File "/home/trufa/workspace/hangpy/src/v2.py", line 134, in startGame
print points.letterGuess()
File "/home/trufa/workspace/hangpy/src/v2.py", line 79, in letterGuess
return self.errList
AttributeError: Score instance has no attribute 'errList'
I don't understand why since I can do this without any trouble:
class One():
def __init__(self):
self.list= [1,2]
class Two(One):
def meth(self):
return self.list
uan = One()
tu = Two()
print uan.list
print tu.meth() ## Both output [1,2]
I'm very new to OOP so I could be doing all kinds of silly mistakes but I can't figure out where!
I think I have posted all the relevant code, but I you think the error might be elsewhere, I can provide it.
As I said I'm very new, so this might have nothing to do with inheritance I just think it called that when you get "something" from within another class (you must be shouting at the screen by now)
You overwrite the original __init__, which is then never called and doesn't initialize the members. You must call the parent's __init__ separately, usually with this snippet:
def __init__(self):
super(Score, self).__init__()
See the docs for super() for details. However, super() only works for so-called new-style classes. You must therefore either change the definition of Play to inherit from object:
class Play(object)
or you call the parent's method directly:
def __init__(self):
Play.__init__(self)
When you inherit from the class Play, you automatically get the attributes that you've created in the definition of Play, but you don't get the attributes that you've created in Play.__init__. You have to explicitly call it like so:
class Score(Play):
def __init__(self):
Play.__init__(self)
self.initialScore = 0
See Boldewyn's suggestion for using super to do this; but IMO you should probably get used to the basic way inheritance works before fiddling with super.
To further clarify, if you don't override __init__ as you have in this case, then it's inherited and called automatically.
You forgot to initialize the superclass.
class Score(Play):
def __init__(self):
super(Score, self).__init__()
self.initialScore = 0

Categories