Python中的类使用
我经常用Python写很多脚本,来分析和绘制实验数据,还会写一些简单的模拟,看看理论和数据的契合度。这些脚本通常都是按照步骤来写的:先计算某个属性,再计算另一个属性,然后绘制这些属性,最后分析图表……
我在想,除了按照步骤写代码,使用类(Class)会有什么好处呢?我可以把实际的分析过程放到函数里,这样就可以把数据传给函数,让它自己处理,但这些函数并不在一个类里面。
使用类能解决什么问题?如果我可以按照步骤写代码,使用类的目的是什么呢?
如果这个问题之前有人问过,我很抱歉,请指引我去相关的内容。
5 个回答
“但是这些函数并没有放在一个类里面。”
其实可以放进去的。
class Linear( object ):
a= 2.
b= 3.
def calculate( self, somePoint ):
somePoint['line']= b + somePoint['x']*a
class Exponential( object ):
a = 1.05
b = 3.2
def calculate( self, somePoint ):
somePoint['exp']= b * somePoint['x']**a
class Mapping( object ):
def __init__( self ):
self.funcs = ( Linear(), Exponential() )
def apply( self, someData ):
for row in someData:
for f in self.funcs:
f.calculate( row )
现在你的计算都放在类里面了。你可以使用一些设计模式,比如委托、组合和命令,来让你的脚本更简单。
在Python中,你不需要使用类——它并不会强迫你使用面向对象编程。如果你更喜欢函数式编程的风格,那也没问题。我在想要建模一些有变化的抽象概念时会使用类,这样可以用类来表示这些变化。正如“类”这个词所暗示的,当你处理的内容自然分成不同的类别时,类就特别有用。但如果只是处理大数据集,我并没有觉得一定要为了遵循面向对象的原则而去使用它。
使用面向对象编程(OOP)时,你会有一些对象,这些对象有相关的功能,而这些功能应该是唯一能修改对象属性(内部变量)的方法。
以前常常会有这样的函数:trim_string(string)
,而在一个string
类中,你可以直接用string.trim()
。这种区别在处理大型复杂模块时特别明显,因为你需要尽量减少各个组件之间的耦合。
OOP还有其他概念,比如继承,但最重要的是要明白,OOP让你关注的是对象,这些对象有操作和消息传递(方法/动词),而不是关注操作(函数/动词)和基本元素(变量)。
面向对象范式的重要性不在于语言机制,而在于思维和设计过程。
你也可以看看这个问题.
结构化编程本身并没有什么错误,只是某些问题更适合用面向对象的设计。
举个例子,在结构化编程语言中,你可能会有:
#Pseudocode!!!
function talk(dog):
if dog is aDog:
print "bark!"
raise "IS NOT A SUPPORTED ANIMAL!!!"
>>var dog as aDog
>>talk(dog)
"bark!"
>>var cat as aCat
>>talk(cat)
EXCEPTION: IS NOT A SUPPORTED ANIMAL!!!
# Lets add the cat
function talk(animal):
if animal is aDog:
print "bark!"
if animal is aCat:
print "miau!"
raise "IS NOT A SUPPORTED ANIMAL!!!"
而在面向对象编程中,你会有:
class Animal:
def __init__(self, name="skippy"):
self.name = name
def talk(self):
raise "MUTE ANIMAL"
class Dog(Animal):
def talk(self):
print "bark!"
class Cat(Animal):
def talk(self):
print "miau!"
>>dog = new Dog()
>>dog.talk()
"bark!"
>>cat = new Cat()
>>cat.talk()
"miau!"
你可以看到,在结构化编程中,每添加一个动物,就得在talk
里加一个if
,还得加一个变量来存储动物的名字,可能还要修改模块里的每个函数。而在面向对象编程中,你可以把你的类看作是独立于其他部分的。当有全局性的变化时,你只需要修改Animal
,如果只是小范围的变化,你只需查看类的定义。
对于简单、顺序的、可能是一次性的代码,使用结构化编程是可以的。