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_typeA
和 file_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"
初始化的文件的方法?
我们再试一下Shape
class,这两种类型是Square
和Triangle
。 错误的编码方式是这样的:
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 名称不区分大小写。
虽然我对 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_typeA
和 file_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"
初始化的文件的方法?
我们再试一下Shape
class,这两种类型是Square
和Triangle
。 错误的编码方式是这样的:
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 名称不区分大小写。