initializing python object with nothing but keyword args - python

I am wondering how to initialize an object in python with only named args, and nothing else, if this is possible.
If the order of self.name = name and self.age = age are swapped, the error is with initializing age. I have these given as keyword args to the object, so why is that not enough? I saw a class in dive into python instantiated with explicitly named keyword arguments and their default (filename=None), so I assumed **kwargs would work too. Thank you

What you're missing is that kwargs need to be explicitly retrieved by name. Here's a modified version of your code, to illustrate. Note the initialization of name and age.
class Person(object):
def __init__(self, **kwargs):
self.name = kwargs.get('name')
self.age = kwargs.get('age')
# you'll probably want to check that all required
# members were initialized.
bob = Person(name='bob', age=45)
print bob
print bob.age
Output:
<__main__.Person object at 0x1074e0bd0>
45

kwargs is a dictionary. So you should rather do this:
class Person(object):
def __init__(self, **kwargs):
self.name = kwargs["name"]
self.age = kwargs["age"]

Related

I'm having an error: "TypeError: 'str' object is not callable" - Python

I'm really confused. I made classes similar to this the one with this one with no errors. So I don't see the problem with this one. Please help!
class champ_info:
def __init__(self, name):
self.name = name
def name(self):
print({self.name}) #I also tried using it with out the {}
v = champ_info('henry')
v.name()
You have an attribute with the same name as a method. When you assign self.name its object shadows the function object you really wanted.
class champ_info:
def __init__(self, name):
self.name = name # <-- this shadows the same-named method
v.name() translates to (1) get object referenced by "name" (its the string 'henry') and (2) call that object. You can't call a string, so boom.
To solve, just come up with a better name for the method, hopefully something that gives a good hint of what it does.
class champ_info:
def __init__(self, name):
self.name = name
def print_me(self):
print(f"{self.name}")
v = champ_info('henry')
v.print_me()

python: modify array from parent method in child method

I have a parent class as follows:
class student:
def __init__(self, name, age, field):
self.name = name
self.age = age
self.field = field
def abilities(self):
abs = ["study", "drink", "party"]
action = np.random.choice(abs, replace = True)
return(action)
Now upon graduation this student becomes a grown-up and his abilities change:
class adult(student):
def abilities(self):
super().abilities()
abs.append("work")
abs.remove("party")
if action == work:
print("paying off that student loan")
This does not work. The error I get is: name 'abs' is not defined.
Now I tried to access the abilities method in the parent class by using super().abilities.abs but then I am referring to the object the function returns and with self.abilities.abs, but then I refer to the class.
Any suggestions as to how to access the array within the parent method from the child are much appreciated.
There are a few flaws in the code you wrote:
You are overwritting a built in function abs in your code. This should not be done.
You are calling super().abilities(), which returns a value without storing and using it.
When calling abs.append("work") you are trying to assign a value to a build in function and not the local variable abs from the parent. Extracting this to a object variable solves the issue. See, self.abs in the constructor
The adult abilities method is not returning anything.
You are not calling the super constructor in adult, which results in adult not storing any of the values passed in the constructor.
A fixed version could look as follows:
import numpy as np
class student:
def __init__(self, name, age, field):
self.name = name
self.age = age
self.field = field
self.abs = ["study", "drink", "party"]
def abilities(self):
action = np.random.choice(self.abs, replace = True)
return action
class adult(student):
def __init__(self, name, age, field):
super(adult, self).__init__(name, age, field)
self.abs.append("work")
self.abs.remove("party")
def abilities(self):
action = super().abilities()
if action == "work":
print("paying off that student loan")
return action
In addition to solving this issue, you should review the object inheritance structure as mentioned in the comment by #chepner.

Python3 Class method inputs; clean solution

I'am using more class based programs, however in some cases it's not handy to provide all self.paramets into a class.
In those cases I want to use a regular input into a function in a class. I figured out a way to achieve both inputs, let me show this in following script:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def myfunc(a):
if (type(a) == str):
name = a
else:
name = a.name
print("Hello my name is " + name)
p1 = Person("John", 36)
p1.myfunc()
print("---------------------")
Person.myfunc("Harry")
Output:
Hello my name is John
---------------------
Hello my name is Harry
First, the name is initialized by the classes self.params.
Second, the name is provided in the method within the class as a string.
So a type check is necessary.
However I don't think this is a clean approach, because when I have >30 methods I need to implement these type checks again, including upcoming type-error results.
Does anyone know a better approach?
The simplest solution is to implement a __str__ method for your class. This method will be called whenever something tries to convert an instance of the class to a string.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return self.name
p = Person('Jane', 25)
print('Hello', p)
'Hello Jane'

Object with __init__ in python

I have written some python code:
class key(object):
def __init__(self,name):
object.__init__(self,age)
this.name = name
this.age = age
def somefunction(self):
print "yay the name is %d" % self.name
baby = key('radan',20)
baby.somefunction()
When I create an instance of key with baby = key('radan',20), I got a TypeError. I don't know why I am getting this error. Is it because of object.__init__(self,age)?
If yes, please help me in explaining why we use object.__init__(self,age) and what the purpose of that is and help me solve this code.
Some pointers:
class Key(object): # in Python, classes are usually named with a starting capital
def __init__(self, name, age): # name all your arguments beside self
self.name = name # use self.name, not this.name
self.age = age
def somefunction(self):
print "yay the name is %s" % self.name
baby = Key('radan',20)
baby.somefunction()
# output: yay the name is radan
Actually, you can can name the self instance parameter whatever you like in Python (even this), but it makes the code harder to read for other people, so just use self.
You don't have to use object.__init__(self, name, age) here. If you remove that line and implement the changes above, your code will work just fine.
Your code contains several errors:
class key(object):
def __init__(self, name, age): # where's your age?
self.name = name # no need to call object.__init__
self.age = age # there is no such thing called "this", use self
def somefunction(self):
print "yay the name is %s" % self.name # use %s as the comment says
baby = key('radan', 20)
baby.somefunction()
output:
>>> baby = key('radan', 20)
>>> baby.somefunction()
yay the name is radan
When you do baby = key('radar', 20) you are actually passing three arguments: the instance, the name and the age. However your initialiser is defined to take exactly two arguments so you get a TypeError.
self is the argument implicitly passed when referring to an instance of an object.
For your __init__ function, I would just do:
def __init__(self, name, age):
self.name = name
self.age = age
So we can assign the arguments passed as attributes to the current instance, conventionally called self.
It makes no sense here to call object.__init__ at all, just remove that line.
Apart from that, everything works fine (except use %s instead of %d).
Testing:
>>> baby = key('radan', 20)
>>> baby.somefunction()
yay the name is radan

TypeError in Python 3.x

I have no idea what is wrong! This is a very simple program and I have done a lot head banging! Please someone enlighten me!
This a lab problem from the CSE 111 - Programming Language II course. They teach Java at the university and the code I wrote in Java works fine.
I just have to create a Student class with some fields to hold the basic information about a student with methods to get and set the attributes. Then create an instance of that class and tryout the methods.
But every time I run this program the following error occurs:
TypeError: set_name() takes exactly 1 positional argument (2 given)
Here is the code I wrote.
class Student:
'''Student class'''
name = None
id = 0
address = None
cgpa = None
def get_name():
return name
def set_name(n):
name = n
def get_id():
return id
def set_id(i):
id = i
def get_address():
return address
def set_address(a):
address = a
def get_cgpa():
return cgpa
def set_cgpa(c):
cgpa = c
#An object of Student class
jack = Student()
jack.set_name('jacky')
print(jack.get_name())
You're not accepting a reference to your instance as the first argument to that method, i.e. your set_name() should be written:
def set_name(self, n):
self.name = n
This is somewhat different from other languages where there is a built-in keyword (such as this) that refers to the current object. Python passes that reference explicitly, as an argument to the method.
All your other methods must be modified similarly.
Note that just setting name = n sets a local variable name which goes away when the method ends; it does not set anything on the instance. You have to explicitly set self.name if you want an instance attribute.
Also, and this is a matter of style, but you do not usually write set and get methods in Python. It is normal practice to set and get attributes directly. If you want to do validation of values, use a property instead. So basically, none of your methods are actually necessary in good style.
However, you don't have an __init__() method. Usually you would pass the desired attributes of the instance when instantiating the class and save these on the instance.
class Student:
def __init__(self, name, id, address, cgpa):
self.name = name
self.id = id
self.address = address
self.cgpa = cgpa
herman = Student("Herman Munster", 12345, "1313 Mockingbird Lane", 4.0)
Try this:
import sys
class Student:
'''Student class'''
self.name = None
self.id = 0
self.address = None
self.cgpa = None
def get_name(self):
return self.name
def set_name(self, n):
self.name = n
def get_id(self):
return self.id
def set_id(self, i):
self.id = i
def get_address(self):
return self.address
def set_address(self, a):
self.address = a
def get_cgpa(self):
return self.cgpa
def set_cgpa(self, c):
self.cgpa = c
You need to pass self as the first argument to each member function of the class. Member variables must then be referred to with self, i.e. self.name. Furthermore, you may wish to include an __init__() function; this serves usually to initialize any member variables, and is called at the instantiation of the class.
Take a look at the Python documentation here for some examples on well-formed classes: http://docs.python.org/tutorial/classes.html#random-remarks
In Python, you need to pass in self for each of your member functions. You also need to reference class variables as self.x, if you want them to take an effect.
Here are a couple examples that you need to apply to the rest of your code.
def set_name(self, n):
self.name = n
def get_cgpa(self):
return self.cgpa
There is some explanation for why this is the case in the documentation.
This is because first argument of methods is self - the class instance.
See What is the purpose of self?
and http://docs.python.org/tutorial/classes.html#class-objects

Categories

Resources