Change the object preview into one of its own attributes - python

How to change object printing preview into desirable name ?
class Person:
def __init___(self):
self.name = name
self.age = age
man1 = Person("Jhon",32)
print(man1)
>>> <__main__.Person object at 0x7f9780554b80>
I need to change the preview of object into specifice attribute .(e.g: obj.name , in this example i want the preview will be "Jhon_Person_obj" instead the adress of it)
This code describe the printing reasult i need.
print(Jhon_Person_obj)
print(Jhon_Person_obj.age)
>>> <__main__.Personobject at 0x7f9780554bb0>
>>> 32

Override the __repr__ method of your class:
# PEP8: Class names should normally use the CapWords convention.
class Pokemon():
def __init__(self, name):
self.name = name
def __repr__(self):
return f"Pokemon(name='{self.name}')"
Usage:
p = Pokemon('Pikachu')
print(p)
# Output
Pokemon(name='Pikachu')

Related

Python extend the __dict__ object with another dict

Let's say I have a class of Person and I want to assign new properties for each instance but I also want to keep track of said new properties, something like:
class Person:
def __init__(self, **kwargs):
self.props = {}
for arg in kwargs:
self.props[arg] = self.__dict__[arg] = kwargs[arg]
But for example, the following code would show why this doesn't gets me what I need:
person = Person(name='Tomer')
person.props['name'] = 'Michael'
print(person.name)
# >> 'Tomer'
How can I keep a reference to the added attributes with the option to edit their source?
The __dict__ object is the dictionary object of your class or instance. There is no need to directly manipulate that, because the class can handle setting the attributes itself. You can simply set the attributes directly without the need of an intermediate props:
class Person:
def __init__(self, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)
Then you can just say:
person = Person(name='Tomer')
print(person.name) # output: "Tomer"
person.name = 'Michael'
print(person.name) # output: "Michael"
I'm not sure if that is what you want, though.
Got my answer, you can just set the __getattr__ function on the Person class which would execute when access to a variable that is not in the class and parent class is accessed.
class P(dict):
def __init__(self, *k, **kwargs):
self.__dict__ = self
super().__init__(*k, **kwargs)
p = P(name = "me", age = 40)
>>> p['name'] == p.name == "me"
True
etc.

How to print one Attribute in a class in Python?

simply i have a class that has a method to print a specific attibute in a class example:
class Attr:
def __init__(self, name,
wattage):
self.name = name
self.wattage = wattage
def print_attr(self):
print("attribute in class is " + getattr(Attr, wattage)
the expected output is:
attribute name is wattage: test
You don't need a helper function for this, Python does not have restricted access. Simply access the attribute directly:
a = Attr("Name", 10)
print(a.wattage)
If you truly want to make a print method like this, there are two ways to do it:
class Attr:
def __init__(self, name, wattage):
self.name = name
self.wattage = wattage
def print_wattage(self):
print(f'Wattage in *instance* is {getattr(self, "wattage")}') # getattr gets by string name
def print_name(self):
print(f"Name in *instance* is {self.name}")

How to give names to class instances instantiated with "for" loops?

As an attribute to a certain class, I'm instantiating a bunch of objects of another class. My problem is that they have ugly names for memory addresses. How do I give them proper names?
class CaseReader(object):
def __init__(self, path):
cases_paths = glob(path + '//*')
cases_names = os.listdir(path)
self.case = [Case(i) for i in cases_paths]
Upon running:
a = CaseReader(path)
a
Out[4]: <__main__.CaseReader at 0x1c6dfc7fa88>
a.case
Out[5]:
[<__main__.Case at 0x1c6dfc99fc8>,
<__main__.Case at 0x1c6dfc99dc8>,
<__main__.Case at 0x1c6dfcaf3c8>,
<__main__.Case at 0x1c6dfcaf448>,
<__main__.Case at 0x1c6dfcaf208>]
Overwrite the __str__ function in the class definition and print what ever attributes you want to see, when you print the reference of the object.
Sample Code
class A:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name

How to define correctly a subclass attribute

I have a Person class and a SubPerson sub-class:
class Person:
def setname(self, name):
self.name = name
def display(self):
print(self.name)
class SubPerson(Person):
def display(self):
print("Name: {0}".format(self.name))
if __name__ == "__main__":
p = SubPerson()
p.display()
But when I call the display method of p I have the following error:
File "./person.py", line 14, in display
print("Name: {0}".format(self.name))
AttributeError: SubPerson instance has no attribute 'name'
Why? How can I fix this?
class Person:
def __init__(self, name=""):
self.name=name
#def setname(self, name):
# self.name = name
#instead of display
def __str__(self):
return self.name
#def display(self):
# print(self.name)
if __name__=='__main__':
p=Person("YourName")
print p
You have to "initialize" your attribute of your Person object.. And i would implement the str method to print your objects its like in C++ std::operator<< ..
And your subclass looks like this:
class SubPerson(Person):
def __str__(self):
return "Name: {0}".format(self.name)
There are some other methods(len,get, and so on..), which you can overwrite for your own Class..
please set "name" first
p.setname("your_name")
or if you dont want to set name, then initialize name attribute in parent class
class Person:
name = "your_name"
Why?
You should read exception message: "AttributeError: SubPerson instance has no attribute 'name'", that clearly indicates that SubPerson's instance p that you have created in main using expression p = SubPerson() don't have attribute 'name' - that is why it throws AttributeError exception.
Lets try your code on active interpreter and see:
>>> class Person:
... def setname(self, name):
... self.name = name
... def display(self):
... print(self.name)
...
>>> class SubPerson(Person):
... def display(self):
... print("Name: {0}".format(self.name))
...
>>> p = SubPerson()
>>> p.name # Notice
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: SubPerson instance has no attribute 'name'
>>>
Notice line p.name - you are getting same exception! Indeed p has no attribute with name 'name' you can use introspection technique to list all attribute of p using __dict__ and inherited attributes using dir() function, see below
>>> p.__dict__
{} # p don't have it any it own attribute
>>> dir(p) # either don't inerited attribute 'name'
['__doc__', '__module__', 'display', 'setname']
>>>
Notice only the attributes that p inherits from Person class are 'display', 'setname' but not name.
How can I fix this?
You have few techniques to rectify your code as below:
Python is dynamic language you can explicitly add new name in object namespace as:
>>> p.name = "grijesh"
>>> p.__dict__ # Now `p` has 'name' attributes
{'name': 'grijesh'}
>>> p.display() # it is safe to call display
Name: grijesh
Use your setname function as #Tasawer Nawaz's answer suggestion.
Use __init__ function and implement object constructor as give in #T.C.'s answer.
Basically in all technique you are attaching 'name' attribute to SubPerson instance object before accessing it in display() function method.
call the setname befoure your print statement.
You should explicitly call
p.setname("name")
before accessing it

Creating an object with a reference to the object that created it

I have a program where an object creates another object. However, the second object that gets created needs to be able to access the first. Is this possible?
EG (pseudocode)
class parentObject():
parentVar = 1
# Create Child
x = childObject()
class childObject():
#Assign Var to the Var of the childs parent
childVar = parent.parentVar
>>> x.childVar = 1
is there a straitforward way to do this?
UPDATE:
I don't want to inheret the class, I need to be able to access the actual object that created it, as each object created from that class has different values.
Why not inherit the class?
class parentObject():
parentVar = 1
class childObject(parentObject):
childVar = parentObject.parentVar
>>> x = childObject()
>>> print(x.childVar)
1
If you are going to have different instances of the class, you should do it as this instead:
class parentObject(object):
def __init__(self):
self.parentVar = 1
class childObject(parentObject):
def __init__(self):
super(childObject, self).__init__()
self.childVar = self.parentVar
>>> x = childObject()
>>> print(x.childVar)
1
If you want a reference to the "parent" class, but inheritance is illogical, consider sending self in to the constructor:
class Room:
def __init__(self, name):
self.name = name
self.furniture = []
def add_chair(self):
self.furniture.append(Chair(self))
def __str__(self):
return '{} with {}'.format(self.name, self.furniture)
class Chair:
def __init__(self, room):
self.room = room
def __str__(self):
return 'Chair in {}'.format(self.room.name)
r = Room('Kitchen')
r.add_chair()
r.add_chair()
print r
print r.furniture[0]
Output:
Kitchen with [<__main__.Chair instance at 0x01F45F58>, <__main__.Chair instance at 0x01F45F80>]
Chair in Kitchen

Categories

Resources