Python - calling class from another classes - python-3.x

I'm trying to access a variable from another class. In my Model class, I'm trying to access to all the other classes that I've written above. For example, I tried to access to ball class from the model class(it's position). But I get an error when I try to access it.
class Ball(object):
def __init__(self, x, y):
initialize variables
self._pos = (x, y)
def set_position(self, x, y):
self._pos = (x , y)
def get_position(self):
return self._pos
class Model(object):
def __init__(self):
self._position = Ball().get_position()
def get_ball_position(self):
return self._position
.
error : __init__() missing 2 required positional arguments: 'x' and 'y'

You first need to create an instance of a ball in your Model class:
self.ball = Ball(x, y) enter coordinates for (x,y).
Then access methods from the object you have created. self.ball.get_position()
Note that here self._position = Ball().get_position() you are attempting to create an instance of a ball and assign it to self._position.
What you want to do is create an instance first, and then call the method on the instance.

Related

Why do I keep getting NameError: name is not defined

I'm a noob to coding and just began my question. I started with python OOP and I ran into some trouble.
class Multidiv:
def __init__(self, mulitple):
self.mulitple = mulitple
def mulitple(self, x, y):
return x * y
def divide(self, x, y):
pass
math = Multidiv(mulitple, 10, 5)
print(math)
I keep getting a nameError and I don't understand why. Please help.
there's a lot of mess in your code.. I suggest you get back to reading documentation/watching videos.
for starter - mulitple is not defined.
secondly, you're sending 10 and 5 but ignoring them in the init function. they won't get into to mulitple function.
you can do what you're trying to achieve like this:
class Multidiv:
def __init__(self, mulitple):
self.action = mulitple #save the string name as a member of the object.
def mulitple(self, x, y):
return x * y
def divide(self, x, y):
pass
math = Multidiv('mulitple') #pass the action name with qoutes as string, otherwise it won't be recognized.
actual_action = getattr(math, math.action) # use builtin function getattr to get the actual wanted method out of the object. (you can read about getattr online)
print(actual_action(10, 5)) call the actual action with the parameters you wish to calculate

dynamic inheritance with type and super

I'm looking for a way to dynamically inherit a parent class with its attributes and methods, by using type for class creation and super for inheritance, like so:
class A:
def __init__(self,a,b):
self.a = a
self.b = b
def some_method(self,q):
return (self.a + self.b)**q
def B_init(self,**kwargs):
super().__init__(**kwargs)
def another_method(self,):
return 1
def class_B_factory(parent_class):
return type(
'B',
(parent_class, some_other_parent_class),
{'__init__':B_init,
'another_method':another_method
}
)
And then be able to call...
model = class_B_factory(A)(a = 1, b = 5)
print(model.some_method(2)) # outputs to (1 + 5)**2 = 36
I'm not sure how to proceed. I don't think I'll need a custom metaclass since I'm pretty sure you can't call the parent class' __init__ method while also creating self in the process. I also tried overriding the default __init__ method outside the scope of class_B_factory like so:
def class_B_factory(parent_class):
return type(
'B',
(parent_class, some_other_parent_class),
{'another_method':another_method
}
)
B = class_B_factory(A)
def B_init(self,**kwargs):
super(B,self).__init__(**kwargs)
B.__init__ = B_init
model = B(a = 1, b = 5)
because I figured type doesn't need __init__ right away, as it is only needed during instantiation. But then I get TypeError: __init__() got an unexpected keyword argument error, which seems like it didn't work, and its not clean anyway.
EDIT: I tried defining the methods outside the factory via the following but I am still unsuccessful. Not sure how to fix it. Python has trouble instantiating maybe?
class A:
...
def B_init(self, produced_class = None, **kwargs):
super(produced_class,self).__init__(**kwargs)
def another_method(self, q, parent_class = None):
if parent_class is not None:
return 3 * parent_class.some_method(self,q) # I expect any parent_class passed to have a method called some_method
return 1
def class_B_factory(parent_class, additional_methods):
methods = {}
for name, method in additional_methods.items():
if "parent_class" in signature(method).parameters:
method = partial(method, parent_class = parent_class) # freeze the parent_class argument, which is a cool feature
methods[name] = method
newcls = type(
'B',
(parent_class,),
methods # would not contain B_init
)
newcls.__init__ = partial(B_init, produced_class = newcls) # freeze the produced class that I am trying to fabricate into B_init here
return newcls
model = class_B_factory(parent_class = A, additional_methods = {"another_method": another_method})
print(signature(model.__init__).parameters) # displays OrderedDict([('self', <Parameter "self">),...]) so it contains self!
some_instance_of_model = model(a = 1, b = 5) # throws TypeError: B_init() missing 1 required positional argument: 'self'
The parameterless form of super() relies on it being physically placed inside a class body - the Python machinnery them will, under the hood, create a __class__ cell variable referring that "physical" class (roughly equivalent to a non-local variable), and place it as the first parameter in the super() call.
For methods not written inside class statements, one have to resort to explicitly placing the parameters to super, and these are the child class, and the instance (self).
The easier way to do that in your code is to define the methods inside your factory function, so they can share a non-local variable containing the newly created class in the super call: ​
def class_B_factory(parent_class):
def B_init(self,**kwargs):
nonlocal newcls # <- a bit redundant, but shows how it is used here
​super(newcls, self).__init__(**kwargs)
def another_method(self,):
​​return 1
​ newcls = type(
​'B',
​(parent_class, some_other_parent_class),
​{'__init__':B_init,
​'another_method':another_method
​}
return newcls
If you have to define the methods outside of the factory function (which is likely), you have to pass the parent class into them in some form. The most straightforward would be to add a named-parameter (say __class__ or "parent_class"), and use functools.partial inside the factory to pass the parent_class to all methods in a lazy way:
from functools import partial
from inspect import signature
class A:
...
# the "parent_class" argument name is given a special treatement in the factory function:
def B_init(self, *, parent_class=None, **kwargs):
nonlocal newcls # <- a bit redundant, but shows how it is used here
​super([parent_class, self).__init__(**kwargs)
def another_method(self,):
​​return 1
def class_B_factory(parent_class, additional_methods, ...):
methods = {}
for name, method in additional_methods.items():
if "parent_class" in signature(method).parameters:
method = partial(method, parent_class=parent_class)
# we populate another dict instead of replacing methods
# so that we create a copy and don't modify the dict at the calling place.
methods[name] = method
​ newcls = type(
​'B',
​(parent_class, some_other_parent_class),
methods
)
return newcls
new_cls = class_B_factory(B, {"__init__": B_init, "another_method": another_method})

I am getting "AttributeError: 'str' object has no attribute

I am getting "AttributeError: 'str' object has no attribute 'model'" on line 26. I can not figure out why? not sure how to correct?
import time
import threading
def test(name,name2):
print(name)
print(name2)
car.show(name)
car.color(name2)
time.sleep(30)
class car():
def __init__(self, model, color):
self.model = model
self.color = color
def show(self):
print("Model is", self.model )
print("color is", self.color )
audi = car("audi a4", "blue")
ferrari = car("ferrari 488", "green")
acura = car("acura" , "black")
BMW = car("BMW" , "blue")
Cadillac = car("Cadillac", "green")
f = open("/home/stuff/script/QT/car.txt", "r") #In car.txt file has car model and color list line by line
threads = []
for x in range (5):
name=(f.readline())
name=name.strip()
name2=(f.readline())
name2=name2.strip()
info = threading.Thread (target=test(name,name2))
threads.append(info)
info.start()
x= +x;
f.close()
Now come to look at it your code has multiple problems.
Firstly in your test method make the following changes
Right now your car class doesn't have a color method. It only has a color field which you can access
def test(name,name2):
print(name)
print(name2)
some_car = car(name, name2)
some_car.show()
print(some_car.color)
time.sleep(30)
if you somehow want to pass arg to the show method use the following method signature
def show(self, name)
the first param if class method is reference to the same object.
Refer here for more info on Python3 classes
Indent your show method, Currently it is outside of the class car and hence most probably the problem is because you are passing the self param to a function and not a class method. So self is being evaluated to a string and when you are printing it using self.model it is throwing the exception
you have problem in these lines:
car.show(name)
car.color(name2)
car is class (and btw the convention is to use Car)
car.show is just a function and you pass it a string,
for example 'car.show('blue')' which causes self.model to fail becasue 'blue'.model is faulty.
I am pretty sure you meant to instantiate a car in your test function
with:
the_car = car(name, name2)
the_car.show()

Create class object with a tuple having tensorflow objects

I have a parametersTheta class which creates neural network as follows:
class parametersTheta:
def __init__(self, weight1, weight2,....):
self.weightName1 = weight1
self.weightName2 = weight2
...
self.sess = tf.Session()
def makeWorkerTheta(self, param):
return parametersTheta(self.sess.run(functionCalculatingTensorWeights, feed_dict={...}))
self.sess.run creates a tuple of all the weight tensors. However, error pops up saying you need to input weight2 and onwards, i.e. the tuple goes into weight1
How can I solve this? Basically, how can I create an instance of class parametersTheta with a tuple?
You can instantiate class with tuple expanded to arguments like this.
parametersTheta(*(weight1, weight2, ...))
An asterisk before a tuple expand it to a corresponding arguments list.

Change Return Value of Class Instance

How can I overwrite a class with one of its attributes?
e.g.
class AListGenerator(list):
def __init__(self, *args):
self._mylist = [word for word in args if 'a' in word]
self = self._mylist # does nothing
>>> x = AListGenerator('mum', 'dad', 'mike', 'aaron')
>>> x
[]
>>> x._mylist
['dad', 'aaron']
How can I make x return x._mylist, so that there's no need to call the _mylist attribute?
>>> x
['dad', 'aaron']
To clarify, I do not want/need a __repr__, I want to be able to do stuff like:
x.append('ryan') and x returning ['dad', 'aaron', 'ryan'], and not just ['ryan'].
You are inheriting from list, so all its methods are already accessible in your class, so you already can do x.append(stuff).
You should (probably always) initiate the base class before doing anything in your __init__ method:
class Stuff(list):
def __init__(self, *args):
# initiate the parent class!
super().__init__(word.lower() for word in args)
# you also can define your own attributes and methods
self.random_ID = 5 # chosen by fair dice roll, guaranteed to be random
x = Stuff("HELLO", "WoRlD")
And then you can print x and do with it everything you can do with a list.

Resources