Class 类与函数

Class 类与函数,class,function,oop,Class,Function,Oop,函数很容易理解,即使对于没有任何编程经验的人来说也是如此,但是具有相当的数学背景。另一方面,课堂似乎更难掌握 假设我想制作一个类/函数,计算一个人的生日年和当前年份的年龄。我应该为此创建一个类还是一个函数? 或者选择取决于场景 另外,我正在研究Python,但我想问题是通用的。创建一个函数。函数做特定的事情,类是特定的事情 类通常有方法,这些方法是与特定类相关联的函数,并执行与类相关联的操作-但是如果您只想执行某些操作,那么只需要一个函数 从本质上讲,类是一种将函数(作为方法)和数据(作为属性)

函数很容易理解,即使对于没有任何编程经验的人来说也是如此,但是具有相当的数学背景。另一方面,课堂似乎更难掌握

假设我想制作一个类/函数,计算一个人的生日年和当前年份的年龄。我应该为此创建一个类还是一个函数? 或者选择取决于场景


另外,我正在研究Python,但我想问题是通用的。

创建一个函数。函数做特定的事情,类是特定的事情

类通常有方法,这些方法是与特定类相关联的函数,并执行与类相关联的操作-但是如果您只想执行某些操作,那么只需要一个函数


从本质上讲,类是一种将函数(作为方法)和数据(作为属性)分组到围绕某种事物的逻辑单元中的方法。如果您不需要分组,则无需创建类。

这取决于场景。如果您只想计算一个人的年龄,那么就使用一个函数,因为您想要实现一个特定的行为

但是,如果您想要创建一个对象,该对象包含一个人的出生日期(可能还有其他数据),允许修改该对象,那么计算年龄可能是与该人相关的许多操作之一,使用类来代替是明智的

类提供了将一些数据和相关操作合并在一起的方法。如果您对数据只有一个操作,那么使用函数并将数据作为参数传递,您将获得等效的行为,代码不那么复杂

请注意,此类类别:

class A(object):
    def __init__(self, ...):
        #initialize
    def a_single_method(self, ...):
        #do stuff

不是一个真正的类,它只是一个(复杂的)函数。合法类应始终至少有两个方法(不计算
\uuuu init\uuuu
)。

在回答您的问题之前:

如果你没有一个<代码>人>代码>类,首先你必须考虑是否要创建一个<代码>人>代码>类。您是否计划经常重复使用

人的概念?如果是这样,您应该创建一个
Person
类。(您可以以传入变量的形式访问此数据,而不必担心数据凌乱和草率。)

回答你的问题:

您可以访问他们的生日,因此在这种情况下,您可能有一个带有
someperson.birthdate
字段的
Person
类。在这种情况下,你必须问自己,
someperson.age
是一个可重用的值吗

答案是肯定的。我们通常更关心年龄而不是出生日期,因此如果出生日期是一个字段,那么年龄肯定应该是一个派生字段。(我们不会这样做的情况:如果我们在计算像
someperson.chanceIsFemale
someperson.positionToDisplayInGrid
或其他不相关的值这样的值,我们不会扩展
Person
类;你只要问问自己,“另一个程序是否关心我正在考虑扩展类的字段?”该问题的答案将决定您是扩展原始类,还是创建一个函数(或者您自己的类,如
PersonalysisData
或其他东西)

比如:创建一个函数。事实上,当你不创建函数时,如果你有如下内容,就必须创建类:

class Person(object):
    def __init__(self, arg1, arg2):
        self.arg1 = arg1
        self.arg2 = arg2

    def compute(self, other):
        """ Example of bad class design, don't care about the result """
        return self.arg1 + self.arg2 % other
在这里,您只需要将一个函数封装在一个类中。这只会降低代码的可读性和效率。事实上,函数
compute
可以这样编写:

def compute(arg1, arg2, other):
     return arg1 + arg2 % other
只有在具有多个函数且保持内部状态(带有属性)有意义时,才应使用类。否则,如果要重新组合函数,只需在新的
.py
文件中创建一个模块即可

,这就解释了我的观点。Jack Diederich展示了为什么在这种情况下类是邪恶的,为什么它是一个如此糟糕的设计,特别是在API之类的东西中。
这是一个相当长的视频,但它是必须看的。

类(或者说它们的实例)用于表示事物。类用于定义特定对象类(其实例)支持的操作。如果您的应用程序需要跟踪人员,则
Person
可能是一个类;该类的实例表示您正在跟踪的特定人员

函数用于计算事物。它们接收输入并产生输出和/或产生效果

类和函数并不是真正的替代品,因为它们不是相同的东西。考虑做一个类来计算一个“生日”和“生日”的人的年龄是没有意义的。“。您可能有或可能没有类来表示

年龄
、和/或
生日
的任何概念。但是,即使年龄是一个类别,也不应将其视为计算一个人的年龄;相反,计算一个人的年龄会产生
age
类的实例

如果您在应用程序中为人员建模,并且您有一个
Person
类,那么将年龄计算作为
Person
类的一种方法可能是有意义的。方法基本上是定义为类的一部分的函数;这就是我前面提到的“定义特定对象类支持的操作”的方式

因此,您可以在person类上创建一个方法来计算此人的年龄(它可能会从person对象中检索生日年,并接收当前年份作为参数)。但是计算仍然是由一个函数完成的(只是一个碰巧是类上的一个方法的函数)

或者,您可以简单地创建一个独立的函数来接收参数(从中检索出生年份的person对象,或者只是出生年份本身)。正如您所注意到的,如果您还没有一个这样的类,那么这就简单多了
class Person(object):
    def __init__(self, id, name, city, account_balance):
        self.id = id
        self.name = name
        self.city = city
        self.account_balance = account_balance

    def adjust_balance(self, offset):
        self.account_balance += offset


if __name__ == "__main__":
    p = Person(123, "bob", "boston", 100.0)
    p.adjust_balance(50.0)
    print("done!: {}".format(p.__dict__))
from collections import namedtuple

Person = namedtuple("Person", ["id", "name", "city", "account_balance"])


def adjust_balance(person, offset):
    return person._replace(account_balance=person.account_balance + offset)


if __name__ == "__main__":
    p = Person(123, "bob", "boston", 100.0)
    p = adjust_balance(p, 50.0)
    print("done!: {}".format(p))