2011-03-15 55 views
3

我从PHP和快速的学习OOP的Python基础PHP的例如知识 我有一个类快速概述面向python的OOP php?

<?php 
class Cat{ 
    private $name; 
    private $age; 
    private $color; 

    public function getName() 
    { 
     return $this->name; 
    } 

    public function setName($value) 
    { 
     $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; 
    } 

} 
?> 

什么是等价于Python的OOP代码?

回答

3

完全等效会是这样:

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 

    ... 

它会工作,但你永远不会做的是Python。原因如下:

  • 在Python中没有什么是真正的私有的,你总是可以绕过使用这种语言的一些技巧的限制。所以你通常更看重执行行为的通信,文档和API。
  • 直接访问属性在Python中是完全正确的。如果在获得或设置时你没有特别的东西,那么你就不会写getter和setter。最好的Python库做到这一点。
  • 你有一种叫'属性'的东西让你在事后改变主意。如果在1个月内,你决定在获取和设置var时做某些事情,则可以在不更改API的情况下执行此操作。

这里是你将如何把它在正确的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 

现在,如果你突然想改变主意,并保证了名字总是当您存储它利用?你只需要添加一个属性:

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() 

的代码更改,但来自外部,它看起来完全一样:

c = Cat('billy') 
print c.name 
# BILLY 
c.name = 'kit' 
print c.name 
# KIT 

主要有哪些好处?

  • 您不必在大部分时间写入getter和setter,它的时间相同,代码更短,因此更易于阅读。
  • 如果你改变主意,你总是可以写一个getter/setter。只有你需要的一个,而不是所有其他的。该API保持一致。
+0

+1是属性的一个很好的例子。 – delnan 2011-03-15 19:28:58

+0

很好的解释,谢谢 – kn3l 2011-03-16 07:47:45

8
class Cat(object): 
    def __init__(self, name, age, color): 
     self.name = name 
     self.age = age 
     self.color = color 

不,我不是在开玩笑。

  1. 削减getter/setter的东西,我们有属性的原因。
  2. 如果您打算拥有一个属性,那么您最好始终拥有它(即从创建开始)或AttributeError。尽管PHP允许你沉默这些(Python不),但它们是所有语言的“代码味道”。
  3. 在Python 2.x中,您需要从object(直接或间接)继承 - 否则,您会从过去的旧式类中得到一个令人讨厌的残留物。只是不打扰它。在Python 3中,你不需要这样的样板(老式的类已经不存在了,如果没有别的,所有的东西都会继承object)。
  4. 这很重要:通过比较几个简短的片段,您不会学习Python(或任何其他语言)。阅读教程,了解SO上的一些真实代码和Python问题。此外,练习练习练习,并检查代码。
+0

非常短于PHP代码。 – kn3l 2011-03-15 17:01:21

+0

这里的旧式课程。 – cmaynard 2011-03-15 17:02:02

+0

@kramthegram:不再。原始版本也有语法错误(缺少冒号)。 – delnan 2011-03-15 17:03:46

2
class Cat(object): 
    def __init__(self, name, age, color): 
     self.name = name 
     self.age = age 
     self.color = color 

setter和getter通常不在Python使用;如果你真的需要在它们中做一些特殊的事情,你可以使用property,所以界面将不会需要改变。由于如果您决定为您设置的每个值添加5,界面将不必更改,因此无需输入额外的功能。

顺便说一句,这不是真的OOP。这只是一个在Python中阐述的C结构。如果你想添加OOP风格的方法,例如,抚摸你的猫,你可以。就在这个添加到类:

def pet(self): 
    # Do whatever petting does to a cat. 
    pass 
+0

'object'或'Object'? – 2011-03-15 17:02:25

+0

'__getattr__','__getattribute__'和'__setattr__'更类似于PHP的'__get'和'__set'。在Python中,我们有一些属性可以使'get' /'set'与普通的旧属性访问/赋值相同。 – delnan 2011-03-15 17:03:16

+0

@delnan:哎呀,你是对的。我将'property'与'__getattr__'混合在一起。我想我不会经常使用它们。固定。 – nmichaels 2011-03-15 17:06:39

2

每个人都有很好的答案,但我想我会包括的例子内置property功能。

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) 
+0

使用'property'作为装饰器实际上更好。此外,你有语法错误(冒号丢失),并在旧式类中滑行(这是集体失败问题吗?我也这样做!)。有关示例,请参见http://www.ideone.com/akR5f。 – delnan 2011-03-15 17:13:59

+0

你不应该这样做,除非有一个重要的,令人信服的理由这样做...... – chmullig 2011-03-15 17:18:26

+0

问题是你不应该使用相同的名称为属性和变量。它会导致无限循环。改用“self._name”这样的成员名称。 – Kabie 2011-03-15 17:23:05

1

您的代码更像是this

但是,除非您需要自定义setter和getter,否则不要这样做。