Python OOP:如何使用标志参数访问方法?

Python OOP: how to use a flag parameter to access methods?

虽然我对 OOP 的基础知识感到困惑,但我不清楚如何在 Python 中完成此操作:

假设我创建了一个 Shape class,并以此为例。

class Shape:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def area(self):
        return self.x * self.y

    def perimeter(self):
        return 2 * self.x + 2 * self.y

    def scaleSize(self,scale):
        self.x = self.x * scale
        self.y = self.y * scale

在我的例子中,我必须创建一个 Class 来输入一个只有两种类型的文件,file_typeAfile_typeB。对于用户来说,将 Class 用于 Type A 并使用 Class 用于 Type B 将异常麻烦。

## use case for an a "read in file name" class `filename`
foo = filename(path = "path/to/file.txt", file_type = "TypeA")

我的问题是,如何限制使用标志 file_type="TypeA" 初始化的文件的 "Type A" 方法,以及限制使用标志 file_type = "TypeB" 初始化的文件的方法?

我们再试一下Shapeclass,这两种类型是SquareTriangle错误的编码方式是这样的:

class Shape:
    def __init__(self, x, y, type):
        self.x = x
        self.y = y
        self.type = type

    if type == "Square":

        def area(self):
            return self.x * self.y

        def perimeter(self):
            return 2 * self.x + 2 * self.y

        def scaleSize(self,scale):
            self.x = self.x * scale
            self.y = self.y * scale

    elif type == "Triangle":

        def hooray(self):
            print("HOORAY! It's hip to be a triangle!")

    else:
        print("'type' must be either Circle or Triangle")

 ## example Class instantiation
 bar = Shape(2, 3, type="Square")

对于这样的 class,我如何创建它使得方法 area 不能用于类型 =="TypeB" 的 Shape

我觉得你需要定义一个妈妈class:

class Shape:
   pass

然后子classes

class Triangle(Shape):
   # whatever methods there are

您所描述的是一个 factory 函数,它根据一些参数创建适当的对象:

def create(type):
   if type=="Triangle":
       return Triangle()
   elif type=="Square":
       return Square()

但这不是很有用,因为调用者必须传递 class 的名称:

c = create("Triangle")

而不只是做:

c = Triangle()

好吧,当 saving/restoring 来自包含程序内存中对象类型的文本文件的程序状态保存时(如果您不想使用 pickle).

那不是你 OOP 的方式! OOP 有助于消除 那些类型的条件。您应该创建一个 Shape 基础 class,然后使用它来为每种单独的形状定义子classes。 subclasses 应该包括那种形状所需的方法。

如果您希望调用者能够使用字符串指定形状,例如因为他们正在使用来自文件或用户的数据,您可以编写一个工厂方法来执行此操作。实际上,您可以向 Python 询问 class 的子 class;无需列出它们! DRY

class Shape(object):
     __subs = {}

     @classmethod
     def of_type(cls, name, *args, **kwargs):
         """Factory method that instantiates Shape subclasses given their name as a string"""
         lname = name.lower()
         subs = cls._Shape__subs
         if cls is Shape:
             if not subs:        # build subclass dictionary
                 subs.update({c.__name__.lower(): c for c in cls.__subclasses__()})
             if lname in subs:   # instantiate the named subclass
                 return subs[lname](*args, **kwargs)
             raise NameError("invalid shape name: %s" % name)
         raise TypeError("of_type() may be called only on Shape base class")

class Square(Shape):
     pass

class Triangle(Shape):
     pass

# set tri to an instance of type Triangle
tri = Shape.of_type("Triangle")

请注意,工厂方法会传递名称后给出的任何参数。 Class 名称不区分大小写。