Python 3:使用OOP在条件语句上将Class更改为Integer

问题描述 投票:1回答:3

不正确的术语道歉,我还是新手。

我想创建一个类初始化器,使用条件,将决定所述类的实例是否会折叠成一个简单的整数。

简化的不工作示例:

class A(object): 
    def __init__(self,a,b):
        self.a = a
        self.b = b
        if self.b == 0:
            return int(a)
    def __repr__(self):
        return str(a)+":"+str(b)

DoesntBecomeAnInt = A(3,4)
WillBecomeAnInt = A(3,0)
print(DoesntBecomeAnInt,WillBecomeAnInt)

##Desired Output:
##3:4, 3

任何帮助将非常感谢!

python python-3.x class oop
3个回答
1
投票
class A:
    def __new__(cls, a, b):
        if b == 0:
            return a
        return super().__new__(cls)
    def __init__(self, a, b):
        print('Initilizing')
        self.a = a
        self.b = b
    def __repr__(self):
        return str(self.a)+":"+str(self.b)

__new__是用于控制新对象创建的方法(因此名称)。在这里,我们检查b中的__new__是否为零,并返回相应类型的实例。

在行动:

>>> DoesntBecomeAnInt = A(3,4)
Initilizing
>>> WillBecomeAnInt = A(3,0)
>>> print(DoesntBecomeAnInt,WillBecomeAnInt)
3:4 3

2
投票

你应该使用魔术方法__new____new__用作工厂,您可以决定应该实例化哪个类。

class A(object):
    def __new__(self, a):
        return int(a)

A(4)
> 4
A(4).__class__
> <type 'int'>

1
投票

You don't.

你想要的行为是完全出乎意料的,有些奇怪。调用A()预计将返回A的一个实例。做其他事情是令人困惑和不直观的,这使得阅读和理解任何调用它的代码变得困难。

Alternative

如果您确实需要此行为,请创建工厂方法:

def make_thing(a, b):
    if 0 == b:
        return int(a)
    else:
        return A(a, b)

显然,你需要一个比make_thing更好的名字,但没有任何背景,我不能给你任何建议。

Avoid the problem if possible

由于A不是一个数字,并且通常与int不兼容,因此将intA存储在同一个变量中也有些奇怪。

如果您所做的只是转换为字符串,那么您根本不需要一个类。类之外的简单方法是更好的选择:

def a_and_b_to_string(a, b):
    if b == 0:
        return str(int(a))
    else:
        return str(a) + ":" + str(b)

如果你做的不止于此,那么你的调用代码可能会看起来像这样:

x = make_thing(input1, input2)
if isinstance(x, A):
    result = x.some_method_from_a() # Or some other calculation requiring an A
else:
    result = 5 * x # Or some other calculation requiring an `int`

这有点傻:你编写一个方法来选择数据类型,然后必须为每个可能的结果编写专门的代码。在这里使用返回单独类型的函数,您无法获得任何好处。我可以想到两个更简单的选择:

  1. 只需将支票移至调用代码即可: if input2 == 0: temp = A(input1, input2) result = temp.some_method_from_a() # Or some other calculation requiring an A else: result = 5 * int(input1) # Or some other calculation requiring an int 如果你走这条路线,你也应该修改A.__init__以投掷ValueError,如果b == 0,因为这将是一个无效状态的A
  2. 无论Ab,修改0以使其正常工作: class A(object): def __init__(self,a,b): self.a = a self.b = b def some_method_from_a(): if self.b == 0: # Some calculation involving only a return int(self.a) * 5 else: # Some other more complex calculation involving both a and b return self.a * self.b * 6 def __repr__(self): if self.b == 0: return str(int(self.a)) else: return str(self.a) + ":" + str(self.b) 然后 x = A(a, b) result = x.some_method_from_a()

但同样,在不知道您实际使用它的情况下很难提供建议。

© www.soinside.com 2019 - 2024. All rights reserved.