When to use self and when not to use self - python

Which class option is preferable and why?
Option 1
class Person():
def __init__(self):
pass
def sayHello(self, name):
print "{} says hello!".format(name)
def driver(self):
for name in names: # names is generated in the driver function by some means of input
self.sayHello(name)
Option 2
class Person():
def __init__(self):
self.name = None
def sayHello(self):
print "{} says hello!".format(self.name)
def driver(self):
for name in names: # names is generated in the driver function by some means of input
self.name = name
self.sayHello()
You can assume that there are more variables than just name and that multiple functions are using these variables. The main point I am trying to make is that the variable value's are changing inside the for loop

Even though your exemple is syntaxically correct, it doesn't help at all understand your question regarding how to use a instance attribute.
From want I'm guessing, there's two questions :
When to use a class method (def foo(self, bar)) ?
When to use a instance attribute (self.name) ?
Instance attribute should be used when you need to "share" a variable between functions or retrieve it from outside a function. That variable will be "attached" to the object (for exemple, the color of a car, the nickname of a user, ...)
If your function / method need to call this kind of variable, it must use self to get it, so you have to set it as the first argument when defining this function.
If you just need a temporary variable to loop over it and do some stuff, you don't need to use a class method, a simple function will do the trick.

Related

Python Function that creates class instances

Hello i want to create a function which creates instances of a class
def make_instance(name_instance)
name_instance=puppy()
class puppy:
def __init__(self,name):
self.name =name
make_instance(cloud)
# when i pass an argument it says the variable is undefined and i use #isinstance() it return False.
Your puppy class needs to take a name value into its constructor, and you're currently not passing in anything.
Also your function doesn't return the instance at all. It simply re-assigns the instance to the variable name_instance that you pass in (losing your input). The return value of make_instance right now is None
My guess is that you want your implementation to look like the following
def make_instance(name_instance)
return puppy(name_instance)
I do want to point out though that this function isn't useful unless it does more than just create the instance, you're just adding wrapper code around the constructor

Difference between methods and attributes in python

I am learning python and doing an exercise about classes. It tells me to add an attribute to my class and a method to my class. I always thought these were the same thing until I read the exercise. What is the difference between the two?
Terminology
Mental model:
A variable stored in an instance or class is called an attribute.
A function stored in an instance or class is called a method.
According to Python's glossary:
attribute: A value associated with an object which is referenced by
name using dotted expressions. For example, if an object o has an
attribute a it would be referenced as o.a
method: A function which is defined inside a class body. If called as an attribute of an instance of that class, the method will get the instance object as its first argument (which is usually called self). See function and nested scope.
Examples
Terminology applied to actual code:
a = 10 # variable
def f(b): # function
return b ** 2
class C:
c = 20 # class attribute
def __init__(self, d): # "dunder" method
self.d = d # instance attribute
def show(self): # method
print(self.c, self.d)
e = C(30)
e.g = 40 # another instance attribute
A method is an attribute, but not all attributes are methods. For example, if we have the class
class MyClass(object):
class_name = 'My Class'
def my_method(self):
print('Hello World!')
This class has two attributes, class_name and my_method. But only my_method is a method. Methods are functions that belong to your object. There are additional hidden attributes present on all classes, but this is what your exercise is likely talking about.
A quick,simplified explanation.
Attribute == characteristics.
Method == operations/ actions.
For example, Let's describe a cat (meow!).
What are the attributes(characteristics) of a cat?
It has different breed, name, color, whether they have spots...etc.
What are methods (actions) of a cat?
It can meow, climb, scratch you, destroy your laptop, etc.
Notice the difference, attributes define characteristics of the cat.
Methods, on the other hand, defines action/operation (verb).
Now, putting the above definition in mind, let's create an object of class 'cat'...meowww
class Cat():
To create attributes, use def init(self, arg1, arg2) - (as shown below).
The 'self' keyword is a reference to a particular instance of a class.
def __init__(self, mybreed, name):
# Attributes
self.breed = mybreed
self.name = name
# Operations/actions --> methods
def kill_mouse(self):
print('Insert some method to kill mouse here')
Notice (above) 'mybreed' is an input argument that the user need to specify, whereas self.breed is an attribute of the instance assigned to 'mybreed' argument. Usually, they're the same (e.g. breed for both, self.breed = breed). Here, it's coded differently to avoid confusion.
And attributes are usually written as 'self.attribute_name' (as shown above).
Now, methods are more like actions, or operations, where you define a function inside the body of a class to perform some operation, for example, killing a mouse. A method could also utilize the attributes that you defined within the object itself.
Another key difference between a method and attribute is how you call it.
For example, let's say we create an instance using the above class we defined.
my_cat = Cat()
To call an attribute, you use
my_cat.name
or
my_cat.breed
For methods, you call it to execute some action. In Python, you call method with an open and close parenthesis, as shown below:
my_cat.kill_mouse()
A method is a function defined in the class. An attribute is an instance variable defined in the class.
Example:
class Example(object):
def __init__(self, name):
self.name = name
def hello(self):
print 'Hi, I am ' + self.name
Here hello is a method, and name is an attribute.
class example:
global a
# a=0
def __init__(self,x,y):
self.fname=x
self.lname=y
def show(self):
return "first name: {} & Last name: {}".format(self.fname,self.lname)
obj1=example('reyan','ishtiaq')
obj2=example('ishtiaq','reyan')
print('method associated with obj1: '+ obj1.show())
print('method associated with obj2: '+ obj2.show())
obj1.a=20
obj2.a=30
print(obj1.a)
print(obj2.a)
output:
method associated with obj1: first name: reyan & Last name: ishtiaq................
method associated with obj2: first name: ishtiaq & Last name: reyan................
20
30
#Below u can see that I made a class called "example" with two class attributes:
variable1 and variable2.
class example():
def init(self, variable1, variable2):
self.variable1 = variable1
self.variable2 = variable1
i did not construct a method inside this class. Notice that variable1 comes first and after comes variable2 inside the init():
#below i created an object "object1" with the example class. I created the example class with two arguments "variable1" and "variable2". "self" does not count), so i have to pass two arguments when calling the example class. I gave two variables "10" and "20".
object1 = example(10,20)
with the code below i just get the value of the first argument, which is 10.
print(object1.variable1)

method to print name of an instance of a class

I am new to classes and writing one to perform a tracking and timing task. Have looked at this but still having trouble getting one aspect of the functionality to work.
Here's the part of what I've got to demonstrate the problem:
class seperate_trackers():
def __init__(self):
print ("class initiated")
def print_instance_name(self):
print (self.__class__.__name__)
Create an instance of it:
track_task1 = separate_trackers()
>> class initiated
Run the method in there:
track_task1.print_instance_name()
>> separate_trackers
That's not what I want!
How can that method be fixed so it returns track_task1 when it is run?
This is not a good idea. If you want your instance to have a name, that should be an attribute of the instance itself (the name of the variabe is just a pointer and it should not represent the object's state).
Try this instead:
# We don't usually use snake case for class names in python (and its 'separate')
class SeparateTrackers():
def __init__(self, name):
self.name = name
instance1 = SeparateTrackers("instance_name")
print(instance1.name) # instance_name
Objects don't know what variables refer to them. There can be any number of references to an object, and none of them is "the real one," they are all equally valid as names for the object. Furthermore, there may be no references that are simple names:
things = [1, "hello", separate_trackers(), 3.14]
There's no useful way to find out what variables refer to an object.
class SeparateTrackers:
def __init__(self, instance_name):
self.instance_name = instance_name
def __str__(self):
return self.instance_name
So you can use something like
a = SeparateTracker("first instance")
print(a) # print instance's name

Python Class Script Running Errors?

I am trying to make a class using Python 2.7.9 and it keeps running into errors.
Here is my script:
class Hero():
def __init__(self, name):
self.health=50
def eat(self, food):
if(food=='apple'):
self.health+=10
self.name=Jeff
Jeff=Hero('Jeff')
def introduce(self, name):
print Jeff.name
def checkAtt():
print Jeff.health
introduce()
It keeps saying name 'Jeff' is not defined.
Your code has numerous problems. The first, that is causing the specific error, is that you attempt to assign:
self.name = Jeff
before you have defined either self or Jeff. self is conventionally only used inside instance methods (like your Hero.eat), where it is the name of the first parameter.
Secondly, your Hero.__init__ doesn't actually assign the name parameter to the name attribute; it should look like:
class Hero(object): # Note inheritance from 'object' for new-style class
def __init__(self, name):
self.name = name # Note assignment of instance attribute
self.health = 50
...
jeff = Hero("Jeff") will call Hero.__init__, creating new Hero instance, setting its name attribute to "Jeff" (and health attribute to 50) and assigning that instance to the name jeff.
Thirdly, you have two standalone functions (introduce and checkAtt) that should probably also be instance methods:
def Hero(object):
...
def introduce(self):
print self.name
...
jeff = Hero("Jeff")
jeff.introduce() # equivalent to 'Hero.introduce(jeff)'
or, if remaining as standalone functions, take a single parameter, the Hero instance to operate on (which should not be called self, again by convention) - there is not much point writing a function that only works if it's run in a scope where the name Jeff is available!
class Hero(object):
...
def introduce(hero):
print hero.name
jeff = Hero("Jeff")
introduce(jeff)
Note the indentation in these two different cases - it is very important in Python. Also, note the different ways of calling introduce depending on whether it's an instance method or a function.
I suggest you read the tutorial on classes and the style guide.

Passing an object as a parameter into a sub-class in python

I've been trying to comprehend python's implementation of OOP.
Essentially I need something which is a superclass that defines some global attributes that al l other classes use as input for their methods. Eg:
This is how i thought it should be done:
class One():
def __init__(self, name):
self.name = name
class Two(One):
def __init__(self, name): # name from class one...
One.__init__(self, name)
def method_using_name_from_one(self, name_from_one):
return name_from_one
I guess that I could do this by just declaring all the methods in class Two as in methods of class one, but I'd much prefer to have them separated. So to recap: I want the parameters for the method in class two to use the attributes declared in class One. So essentially I want to pass in an instantiated object as the parameter arguments for class Two methods.
When you say
class Two(One):
One isn't a parameter of class Two. That means class Two inherits from class One. In other words, unless you override a method, it gets everything class One has. edit: When I say this, I mean parameters and functions, I don't mean an instance of the class. Since you have:
def __init__(self, name): # name from class one...
One.__init__(self, name)
self.name is in class Two. In other words, you could just say...
def method_using_name_from_one(self):
return self.name
One thing I would suggest is changing your class One declaration to:
class One(object):
This means it inherits from object, it doesn't mean it's getting passed an object :)
Is this what you meant? Maybe I didn't understand correctly.
If you want the name parameter from One, you could say
def method_using_name_from_one(self, oneInstance):
return oneInstance.name

Categories

Resources