How to create an object with function created outside class in Python? - python

I have just started learning OOP in python and I have learned basics like creating class and it's methods, variables and Constructors. Now to create an object we use following steps.
class Example: #Class
name = None
number = None
def __init__(self, name, number): #Constructor
self.name = name
self.number = number
#Step 1
harry = Example("Harry", 45) #Creates an Object
Now here we have manually created Object of Example class named harry.
I have a question that how to create an object with a function.
Like we created a function outside the class and we passed arguments to like name and number and when that function is called it will create a Object of class.

Are you looking for something like this ?
def build_object(name, number):
# returns Example object initialized with name and number
return Example(name, number)

You're talking about Factory Methods
To create objects in functions and returning it would be like:
class Example:
def __init__(self, name, number):
self.name = name
self.number = number
def object_creator(name, number):
new_obj = Example(name, number)
return new_obj
if __name__ == "__main__":
example_object = object_creator("Iago", 1)
print(example_object.name)
print(example_object.number)

Not sure what do you mean exactly.
in oop you can create a function/method then you can from it's object or class.
class Example: #Class
name = None
number = None
def __init__(self, name, number): #Constructor
self.name = name
self.number = number
def your_function(self, x, y):
return x + y
#Step 1
harry = Example("Harry", 45) #Creates an Object
result = harry.your_function(5, 2)
print (result)
output : 7

Related

How to edit a instance variable?

I'm new to python and as I was doing an assignment for class, I got stuck using init method.
class Customer(object):
def __init__(self, number, name):
self.name = name
self.number = number
self.orders = []
def addorder(self, order):
self.orders.extend(order)
return self.orders
def __str__(self):
return str(self.orders)
Customer('308','John').addorder((1,2,3,4))
print(Customer('308','John'))
The output is an empty list [].
I want the output to be [1,2,3,4]
What am I doing wrong here?
The issue is that you have two Customer objects. I.e. your print line:
print(Customer('308','John'))
Is creating a new Customer object with a number of '308' and a name of 'John'. It's completely unrelated to the customer on the previous line.
To fix this, you should assign your first object to a variable (think of it like a handle, that lets you access the object), and then print that:
john = Customer('308','John')
john.addorder((1,2,3,4))
print(john)
You're creating two instances of the class
class Customer(object):
def __init__(self, number, name):
self.name = name
self.number = number
self.orders = []
def addorder(self, order):
self.orders.extend(order)
return self.orders
def __str__(self):
return str(self.orders)
customer = Customer('308','John')
customer.addorder((1,2,3,4))
print(customer)
Keep in mind that each time you "call" a class, you instantiate a new object (this is why in many languages other than Python, this actually requires the keyword new). So, in your example, you're instantiating two different objects (that don't share their properties). Instead, you should save them in a variable:
customer = Customer("308", "John")
customer.addorder((1, 2, 3, 4))
print(customer)

Python object inside other objects are not isolated

I was expecting the object items inside other python objects are isolated.
However, the following code shows my expected result is wrong. It seems python uses a central item_list for all Group items. How can I fix this?
class Item:
name = ''
def __init__(self, name):
self.name = name
class Group:
item_list = []
def __init__(self, item):
self.item_list.append(item)
g2 = Group(Item('bb1'))
g2.item_list.append(Item('bb2'))
group_list = []
group_list.append(Group(Item('aaa')))
group_list.append(g2)
group_list.append(Group(Item('ccc')))
print('len = ', len(group_list[-1].item_list))
print('bb2 = ', group_list[1].item_list[1].name)
Result
len = 4
bb2 = bb1
Version
python3 --version
Python 3.5.2
Well, first of all we should make a difference between class attributes and instance attributes. A class attribute (like item_list) belongs to the class itself (in this case "Group"), so it will be accessible by calling Group.item_list. On the other hand, you can define a item_list for every instance of Group by defining self.item_list = [] inside the Group class constructor (__init__).
The Group.item_list array will be unique for the whole class, and thus will be suitable to store things that you want to share across instances (such as g2).
The self.item_list array (that will be different for each instance of Group) will hold values exclusively for the instance itself, so each Group will have its own item_list.
I think you are aiming for the second approach (instance variables) so you should move the definition of item_list = [] inside the class constructor.
The result should look like this:
class Item:
def __init__(self, name):
self.name = name
class Group:
def __init__(self, item):
self.item_list = []
self.item_list.append(item)
item1 = Item("itemName")
group1 = Group(item1)
# This should print an array containing the *item1* instance
print(group1.item_list)
print(group1.item_list[0] == item1)
Variables that are declared outside of the __init__ method (in this case item_list) are shared between all instances of a class (called class variables), which is why your expected result is wrong.
On the other hand, variables inside the __init__ only belong to the given instance of that class.
Your using class variables, which are similar C++ static variables inside classes (i.e. that variable is shared by ALL class instances). You need to put it inside the __init__ (constructor) to make it so each class creates its own version:
class Item:
def __init__(self, name):
self.name = name
class Group:
def __init__(self, item):
self.item_list = []
self.item_list.append(item)
# Though typically you would also have a function like this:
def add_item(self, item):
self.item_list.append(item)
g2 = Group(Item('bb1'))
g2.item_list.append(Item('bb2'))
group_list = []
group_list.append(Group(Item('aaa')))
group_list.append(g2)
group_list.append(Group(Item('ccc')))
print('len = ', len(group_list[-1].item_list))
print('bb2 = ', group_list[1].item_list[1].name)
Instance vs class attributes is covered in other answers. I want to add that you can avoid having shared instance variables by using an immutable type (e.g. tuple) instead of a mutable type (e.g. list) for class attributes. Like that they won't be shared among instances while still allowing you to define class attributes.
class Item:
name = ''
def __init__(self, name):
self.name = name
class Group:
item_list = tuple()
def __init__(self, item):
self.item_list += (item,)

How is the pythonic way to create a reference to a own python class instance and use it?

I would like to store the instance of a class in a container like a list. Other classes/methods should access this instance.
Below is a code snipped which defines a data point.
class dataPoint(object):
def __init__(self, name, typeUUID, value = None):
self.name = name
self.typeUUID = typeUUID
self.value = value
I like to define a method which gives me the reference (no copy constructor, etc.) to this object. Maybe like this:
def getRef(self):
return ???
These references I like to use in different list. The reference I like to use to set properties/call functions of the data point. Below is some pseudocode:
# define a conatiner with datapoints
myContainer = [dataPoint("temperature","double",273.15), dataPoint("power","double",230), dataPoint("errorcode","uint32",666)]
# define interfaces which refers to the datapoints
interface1 = [ref("temperature"), ref("power")]
interface2 = [ref("errorcode"), ]
interface3 = [ref("temperature"), ref("power"), ref("errorcode")]
# set temperature to 300K
ref("temperature") = 300.0
# interfaces
print (interface1[ref("temperature")]) --> 300K
print (interface3[ref("temperature")]) --> 300K
How to do this in Python and how to do this pythonic?
You could put the "instance-container" in the class itself:
class DataPoint:
instances = {}
def __init__(self, name, typeUUID, value=None):
self.name = name
self.typeUUID = typeUUID
self.value = value
self.instances[name] = self
#classmethod
def get(cls, name):
return cls.instances[name]
Then you can use it like this:
>>> d1 = DataPoint("foo", "12345")
>>> d2 = DataPoint("bar", "67890")
>>> DataPoint.get("foo")
<DataPoint object at 0x.........>

Python how to find an object by its attributes?

Is there a way to get an object by matching it up with its attributes?
For example:
class band:
def __init__(self, name, number):
self.name = name
self.number = number
rivers = band("rivers", 1)
patrick = band("pat" , 2)
brian = band("brian" , 3)
scott = band("scott", 4)
In this code, is there a way for me to use a number(lets say 1), to find the object rivers within the band class and get its name attribute?
Thank you for taking your time to read this and have a nice day.
In this code, is there a way for me to use a number(lets say 1), to find the object rivers within the band class and get its name attribute?
In this code, NO. Because you do not save the value of name to the class property.
However, if your class structure was like:
class band:
def __init__(self, name, number):
self.number = number
self.name = name # <--- Here is the difference
you could have done it. Let say rivers, patrick, brian and scott are part of the list as:
my_list = [rivers, patrick, brian, scott]
Iterate over the list and print the name of class for which value of number is 1 as:
for item in my_list:
if item.number == 1:
print item.name
You may store a dictionary mapping number to band in order to achieve that.
For example
bands = {}
class band:
def __init__(self, name, number):
self.number = number
self.name = name
bands[number] = self
def getBandFromNumber(number):
return bands[number]

Sub functions in Python

Im writing a basic program in Python.
In the program, there is an array called abc. The array contains the following data:
birthdate and name.
Instead of using:
abc[1]
I want to create sub function, like:
abc.name()
That will return the value of abc[1]
How can i create a function like this (with dot)? Thanks!!
You will want to use a class like this:
class abc():
def __init__(self, birthday, name):
self.__birthday = birthday
self.__name = name
def birthday(self):
return self.__birthday
def name(self):
return self.__name
Now just create abc
person = abc('5/04/1984', 'Nick Stone')
And get the data like so:
bday = person.birthday()
name = person.name()
As said, you can't add such 'function' to your value, it's necessary to create a class definition if you need to use .dot notation. Basic example:
class abc():
# constructor, initializing object state
def __init__(self,item):
self.item=item
# here you define name and body of your function
def name(self):
# return just second item from our "item" value (string, array, list, etc.)
return self.item[1]
Now, you can create object of class abc and call it's 'name function':
> myData=abc('123')
> myData.name()
'2'
> myData=abc(['birth','name'])
> myData.name()
'name'

Categories