Quick overview OOP php to python?
I am from PHP and quick learn OOP Python base PHP 's knowledge for example I have a class
<?php
class Cat{
private $name;
private $age;
private $color;
public function getName()
{
return $this->name;
}
public function setName($value)
{
开发者_StackOverflow社区 $this->name = $value;
}
public function getAge()
{
return $this->age;
}
public function setAge($value)
{
$this->age = $value;
}
public function getColor()
{
return $this->color;
}
public function setColor($value)
{
$this->color = $value;
}
}
?>
What is equivalence to python OOP code?
class Cat(object):
def __init__(self, name, age, color):
self.name = name
self.age = age
self.color = color
No, I'm not joking.
- Cut that getter/setter stuff, we have properties for a reason.
- If you're going to have an attribute, you better have it all the time (i.e. from creation onward), or
AttributeError
s ensue. Even though PHP allows you to silence those (Python doesn't), they're a "code smell" in all languages. - In Python 2.x, you need to inherit from
object
(directly or indirectly) - otherwise, you get one of those nasty relicts from the past, old-style classes. Just don't bother with it. In Python 3, you don't need that boilerplate though (old-style classes are gone, everything inheritsobject
if nothing else). - And this is important: You won't learn Python (or any other language) by comparing a few short snippets. Read a tutorial, some real code and Python questions on SO. Also, practice practice practice and have the code reviewed.
An exact equivalent would be this:
class Cat(object):
def __init__(self, name...):
self.__name = name # __ make the var private
...
def getName(self):
return self.__name
def setName(self, name):
self.__name = name
...
It will work, but you would never do that in Python. Here is why:
- Nothing is really private in Python, and you can always bypass restrictions using some tricks in this language. So you usually value more communication, doc and API that enforcing a behaviour.
- Accessing directly attribute is perfectly fine in Python. If you don't something special while getting or setting, then you don't write getters and setters. The best Python libs do this.
- You have something called 'properties' allowing you to change your mind after the fact. If in 1 month, you decide to do something while getting and setting a var, you can do it without changing you API.
Here is how you would to it in proper Python:
class Cat(object):
def __init__(self, name):
self.name = name
c = Cat('billy')
print c.name
# billy
c.name = 'kit'
print c.name
# kit
Now, what if suddenly you want to change your mind and ensure the name is always capitalize on when you store it ? You just add a property:
class Cat(object):
def __init__(self, name):
self._name = name # '_' is just a convention and does nothing
@property # when you do cat.name, it will call this function
def name(self):
return self._name
@name.setter # when you do cat.name = x, it will call this function
def name(self, name):
""" Make the name uppercase when setting it """
self._name = name.upper()
The code change, but from outside, it looks exactly the same:
c = Cat('billy')
print c.name
# BILLY
c.name = 'kit'
print c.name
# KIT
What are the main benefits?
- You don't have to write getter and setter most of the time, it same times and make the code shorter, hence easier to read.
- If you change your mind, you can always write ONE getter/setter. Only the one you need, not all the other ones. The API keeps looking consistent.
class Cat(object):
def __init__(self, name, age, color):
self.name = name
self.age = age
self.color = color
Setters and getters are not usually used in Python; you can use property if you really need to do something fancy in them, so the interface won't ever need to change. Since the interface won't have to change if you decide to add 5 to every value you set, there's no need to type out the extra functions.
Incidentally, this isn't really OOP. It's just a C struct spelled out in Python. If you want to add OOP-style methods for, say, petting your cat, you can. Just add this to the class:
def pet(self):
# Do whatever petting does to a cat.
pass
Your code is more like this.
However, unless you need customized setter and getter, don't do this.
Everyone has good answers, but I thought I'd include an example of the built-in property
function.
class Cat(object):
def __init__(sef, name, age, color):
self._name = name
self._age = age
self._color = color
def get_name(self):
return self._name
def set_name(self, value):
self._name = value
def get_age(self):
return self._age
def set_age(self, value):
self._age = value
def get_color(self):
return self._color
def set_color(self, value):
self._color = value
name = property(get_name, set_name)
age = property(get_age, set_age)
color = property(get_color, set_color)
精彩评论