class Freelencer:
company="google"
level=0
def upgradelevel(self):
self.level=self.level+1
class Employee:
company="visa"
ecode=120
class Programmer(Freelencer,Employee):
name="rohit"
p=Programmer()
p.upgradelevel()
print(p)
I want to print value of level is changed to 1. Below is the workflow of the code.
you are printing the object. you need to point "self.level".
print(p.level)
In either the Freelencer or Programmer class, you need to define a __str__ method that returns the string that should be shown when you print() the object. You could write a method as simple as this:
def __str__(self):
return 'level ' + str(self.level)
Then print(p) will show
level 1
You might need to override the print method in the Programmer class. use
def __repr__(self):
print(self.name) # or whatever you want to print
Related
I would like to replace an object instance by another instance inside a method like this:
class A:
def method1(self):
self = func(self)
The object is retrieved from a database.
It is unlikely that replacing the 'self' variable will accomplish whatever you're trying to do, that couldn't just be accomplished by storing the result of func(self) in a different variable. 'self' is effectively a local variable only defined for the duration of the method call, used to pass in the instance of the class which is being operated upon. Replacing self will not actually replace references to the original instance of the class held by other objects, nor will it create a lasting reference to the new instance which was assigned to it.
As far as I understand, If you are trying to replace the current object with another object of same type (assuming func won't change the object type) from an member function. I think this will achieve that:
class A:
def method1(self):
newObj = func(self)
self.__dict__.update(newObj.__dict__)
It is not a direct answer to the question, but in the posts below there's a solution for what amirouche tried to do:
Python object conversion
Can I dynamically convert an instance of one class to another?
And here's working code sample (Python 3.2.5).
class Men:
def __init__(self, name):
self.name = name
def who_are_you(self):
print("I'm a men! My name is " + self.name)
def cast_to(self, sex, name):
self.__class__ = sex
self.name = name
def method_unique_to_men(self):
print('I made The Matrix')
class Women:
def __init__(self, name):
self.name = name
def who_are_you(self):
print("I'm a women! My name is " + self.name)
def cast_to(self, sex, name):
self.__class__ = sex
self.name = name
def method_unique_to_women(self):
print('I made Cloud Atlas')
men = Men('Larry')
men.who_are_you()
#>>> I'm a men! My name is Larry
men.method_unique_to_men()
#>>> I made The Matrix
men.cast_to(Women, 'Lana')
men.who_are_you()
#>>> I'm a women! My name is Lana
men.method_unique_to_women()
#>>> I made Cloud Atlas
Note the self.__class__ and not self.__class__.__name__. I.e. this technique not only replaces class name, but actually converts an instance of a class (at least both of them have same id()). Also, 1) I don't know whether it is "safe to replace a self object by another object of the same type in [an object own] method"; 2) it works with different types of objects, not only with ones that are of the same type; 3) it works not exactly like amirouche wanted: you can't init class like Class(args), only Class() (I'm not a pro and can't answer why it's like this).
Yes, all that will happen is that you won't be able to reference the current instance of your class A (unless you set another variable to self before you change it.) I wouldn't recommend it though, it makes for less readable code.
Note that you're only changing a variable, just like any other. Doing self = 123 is the same as doing abc = 123. self is only a reference to the current instance within the method. You can't change your instance by setting self.
What func(self) should do is to change the variables of your instance:
def func(obj):
obj.var_a = 123
obj.var_b = 'abc'
Then do this:
class A:
def method1(self):
func(self) # No need to assign self here
In many cases, a good way to achieve what you want is to call __init__ again. For example:
class MyList(list):
def trim(self,n):
self.__init__(self[:-n])
x = MyList([1,2,3,4])
x.trim(2)
assert type(x) == MyList
assert x == [1,2]
Note that this comes with a few assumptions such as the all that you want to change about the object being set in __init__. Also beware that this could cause problems with inheriting classes that redefine __init__ in an incompatible manner.
Yes, there is nothing wrong with this. Haters gonna hate. (Looking at you Pycharm with your in most cases imaginable, there's no point in such reassignment and it indicates an error).
A situation where you could do this is:
some_method(self, ...):
...
if(some_condition):
self = self.some_other_method()
...
return ...
Sure, you could start the method body by reassigning self to some other variable, but if you wouldn't normally do that with other parametres, why do it with self?
One can use the self assignment in a method, to change the class of instance to a derived class.
Of course one could assign it to a new object, but then the use of the new object ripples through the rest of code in the method. Reassiging it to self, leaves the rest of the method untouched.
class aclass:
def methodA(self):
...
if condition:
self = replace_by_derived(self)
# self is now referencing to an instance of a derived class
# with probably the same values for its data attributes
# all code here remains untouched
...
self.methodB() # calls the methodB of derivedclass is condition is True
...
def methodB(self):
# methodB of class aclass
...
class derivedclass(aclass):
def methodB(self):
#methodB of class derivedclass
...
But apart from such a special use case, I don't see any advantages to replace self.
You can make the instance a singleton element of the class
and mark the methods with #classmethod.
from enum import IntEnum
from collections import namedtuple
class kind(IntEnum):
circle = 1
square = 2
def attr(y): return [getattr(y, x) for x in 'k l b u r'.split()]
class Shape(namedtuple('Shape', 'k,l,b,u,r')):
self = None
#classmethod
def __repr__(cls):
return "<Shape({},{},{},{},{}) object at {}>".format(
*(attr(cls.self)+[id(cls.self)]))
#classmethod
def transform(cls, func):
cls.self = cls.self._replace(**func(cls.self))
Shape.self = Shape(k=1, l=2, b=3, u=4, r=5)
s = Shape.self
def nextkind(self):
return {'k': self.k+1}
print(repr(s)) # <Shape(1,2,3,4,5) object at 139766656561792>
s.transform(nextkind)
print(repr(s)) # <Shape(2,2,3,4,5) object at 139766656561888>
Here is the task: Write a class called LineUp.This class should contain
one (private) field (called acts) to store up to 30 acts. This field should be initialised in the constructor.
A method add_act that takes an Act (keep in mind I've written code above this with 'Act' and that's all fine) as an argument and adds it to acts if there are fewer than 30 acts already, otherwise a message “The festival is full!” should be printed,
add a method toString or str which produces a nice string with full line-up,
add a method print which prints a nice string with the full line-up.
I'm assuming that the first point is asking for a list. I think I've found a way to have a list in a class, but it has the same name (LineUp, as opposed to 'acts'). Here's what I have
class LineUp(list):
def __init__(self):
self.acts = []
def add_act():
if len(acts) >= 30:
print("The festival is full!")
else:
acts.append(Act)
def __str__(self):
string = "LineUp" + str(LineUp)
def println(self):
print(__str__(self))
Thanks in advance! Keep in mind this is my first draft.
EDIT: should I actually use a dictionary, not a list? Know that in another file I'm testing this code
You don't nee to inherit from list or get acts as parameter. To create a list for the class use self.acts in the constructor. You should also add __repr__
class LineUp:
def __init__(self):
self.acts = []
def add_act(self, act):
if len(self.acts) >= 30:
print("The festival is full!")
else:
self.acts.append(act)
def __repr__(self):
return f'LineUp{str(LineUp)}'
def __str__(self):
return f'LineUp{str(LineUp)}'
def println(self):
print(f'LineUp acts:{[act for act in self.acts]}')
Notice that str(LineUp) will return something like <class 'ExampleTest.LineUp'>, you might want to edit it.
I'm trying to create my own class that acts like a regular type, like this:
class CustomType:
def __init__(self, content):
self.content = content
def __str__(self):
return self.content
This means I can do something like this:
a = CustomType("hi there")
print(a) # 'hi there'
But the problem is that I have to use a = CustomType("hi there"). Is there a way I can do something like a = /hi there\ or a similar solution that lets me create my own syntactic sugar?
Thanks.
No. Python does not support creating new syntax.
Note: I would not suggest doing this.
You can't do that because the parser wouldn't know to look for it, but if you wanted something similar, you could create a custom class that returns a new instance of CustomType when divided by a string:
class CustomSyntax:
def __truediv__(self, value):
return CustomType(value)
Then if you had an instance of that class (let's call it c), you could divide it by a string any time you wanted an instance of CustomType:
a = c/'hi there'
b = c/'hello world'
However, that's a little weird, and you'd be best off sticking to your regular constructor.
I realize I've been pretty much spamming this forum lately, I'm just trying to break my problems down since I'm supposed to create a yahtzee game for assignment. My code is currently looking like this:
class Player:
def __init__(self,name):
self.name=name
self.lista={"ones":0,"twos":0,"threes":0, "fours":0,"fives":0,"sixs":0,"abovesum":0,"bonus":0,"onepair":0,"twopair":0,"threepair":0,"fourpair":0,"smalladder":0,"bigladder":0,"house":0,"chance":0,"yatzy":0,"totalsum":0}
self.spelarlista=[]
def __str__(self):
return self.name
def welcome(self):
print("Welcome to the yahtzee game!")
players = int(input("How many players: "))
rounds=0
while not players==rounds:
player=input("What is your name?: ")
rounds=rounds+1
self.spelarlista.append(Player(player))
print(self.spelarlista)
def main():
play=Player("Joakim")
play.welcome()
for key in ["names","ones","twos","threes","fours","fives","sixs","abovesum","bonus","onepair","twopair","threepair","fourpair","smalladder","bigladder","house","chance","yatzy","totalsum"]:
print("%-20s"%key)
main()
My goal is that its gonna look something like this: https://gyazo.com/26f997ed05c92898d93adaf0af57d024
If you look at my method "welcome", I do want to print my self.spelarlista, just to see how its gonna look, but all I get is "Player object at 0x7fac824....", I realize something is wrong with my str, how should I change it?
If you are getting Player object at 0x7fac824 or anything similar, it seems that you are calling the repr on the object (indirectly), which in turn calls the object's __repr__ method.
class Player:
# ...
def __repr__(self):
return self.name
# ...
Since there is no __str__ method defined, __str__ will also default to calling __repr__.
__repr__ returns a string representation of the object (usually one that can be converted back to the object, but that's just a convention) which is what you need.
When you print a list of objects python doesn't call the objects __str__ method but the container list. If you want to print them all you can call the __str__ method by applying the built-in function str() on them using map() or a list comprehension and join them with str.join() method.
print(' '.join(map(str, self.spelarlista)))
Or as another alternative approach you can define a __repr__ attribute for your objects, which returns the official string representation of an object:
>>> class A:
... def __init__(self):
... pass
... def __repr__(self):
... return 'a'
...
>>> l = [A()]
>>>
>>> print l
[a]
I have something like this:
class exampleClass(object):
def doSomething(self,number):
return number + 1
class exampleClass2(exampleClass):
def callDefDoSomething(self):
print exampleClass.doSomething(5)
exampleClass2.callDefDoSomething()
-
TypeError: unbound method callDefDoSomething() must be called
with exampleClass2 instance as first argument (got nothing instead)
I started to learn about objects in Python but i cant find solution for this :(
You need to create an instance of the class, i.e., an active object, to make things work:
class exampleClass(object):
def doSomething(self,number):
return number + 1
class exampleClass2(exampleClass):
def __init__(self):
self.member1 = exampleClass()
def callDefDoSomething(self):
print self.member1.doSomething(5)
object2 = exampleClass2()
object2.callDefDoSomething()
doSomething is a method of exampleClass. Therefore, it has to be called for an instance of this class.
In callDefDoSomething, you use
exampleClass.doSomething(5)
exampleClass, however, is not an instance of this class but the class itself. What you want to use here is
self.doSomething(5)
self refers to the instance of exampleClass2, for whichcallDefDoSomethingsis invoked, which, due to inheritance, is an instance ofexampleClass`.
Regular class methods can only be called for instances not for classes. So if you want to call callDefDoSomething you have to first instantiate exampleClass2. You also have to instantiate exampleClass inside the call to callDefDoSomething.
class exampleClass(object):
def doSomething(self,number):
return number + 1
class exampleClass2(exampleClass):
def callDefDoSomething(self):
exampleClassInstance = exampleClass()
print exampleClassInstance.doSomething(5)
exampleClass2Instance = exampleClass2()
exampleClass2Instance.callDefDoSomething()
If you want to call methods on classes you should try classmethods. Check the documentation on classes in the python tutorial.
You can use this:
class exampleClass(object):
def doSomething(self,number):
return number + 1
class exampleClass2(exampleClass):
def callDefDoSomething(self):
print super(exampleClass2,self).doSomething(5)
example = exampleClass2()
example.callDefDoSomething()