代码之家  ›  专栏  ›  技术社区  ›  dre_84w934

像swift中的python类扩展?

  •  0
  • dre_84w934  · 技术社区  · 8 年前

    我是python的新手,来自swift,我想知道以下几点。在SWIFT中,如果我想给现有的类添加一个功能,我可以做一些类似的事情(如书中的例子):

    extension Double {
        var km: Double { return self * 1_000.0 }
        var m: Double { return self }
        var cm: Double { return self / 100.0 }
        var mm: Double { return self / 1_000.0 }
        var ft: Double { return self / 3.28084 }
    }
    let oneInch = 25.4.mm
    

    我真的很喜欢这个功能,我想知道在python中是否有类似的东西,或者有其他更好的方法,我没有看到,因此这在python中没有任何意义。

    3 回复  |  直到 8 年前
        1
  •  2
  •   kabanus    8 年前

    为了完整起见,我认为这是你应该做的(同样也是迅速的!):

    class Meter(float):
        def to_km(self): return self * 1000.0 
        def to_m (self): return self 
        def to_cm(self): return self / 100.0 
        def to_mm(self): return self / 1000.0 
        def to_ft(self): return self / 3.28084 
    oneInch = Meter(25.4).to_mm()
    print(oneInch)
    

    明确你的对象代表一个米,并且你正在把它转换成某种东西。

    如果你想要一些语法糖, 我不确定是否有用 ,可以重写项目getter,这样就不必使用 () :

    class Meter(float):
        conversions = {
            'km':1000,
            'cm':.01,
            'mm':.001,
            'ft':1/3.28084
        }
        def __getattr__(self,x):
            try:
                return self*Meter.conversions[x]
            except KeyError:
                raise KeyError("No such conversion!")
    oneInch = Meter(25.4).mm
    print(oneInch)
    

    添加转换非常简单:

    Meter.conversions['whatever'] = 123.123
    
        2
  •  2
  •   AKX Bryan Oakley    8 年前

    不,不能像这样扩展内置类 float 或 int .

    >>> int.double = lambda self: self * 2
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: can't set attributes of built-in/extension type 'int'
    

    (不过,您可以修改非内置类,但实际上 不应该 ,因为代码这样做很难解释。)

    您的特定示例最好由以下单元库提供 pint --使用这样的库可以防止 $125 million mistakes doing math between metric and imperial units 也是。

        3
  •  1
  •   ChootsMagoots    8 年前

    你可以建立父类的子类。如果您正在编写自己的代码,有时这是一个好主意,但扩展类似pandas数据帧的内容可能是一个坏主意

    我没有花太多时间为你搜索,但这是我发现的最好的: https://docs.python.org/3/tutorial/classes.html

    这也是我写的一些非常糟糕的代码,试图向我的女朋友解释类继承。请注意 Car 班上还有 car.roll_up_windows() 和 car.roll_down_windows() 以及 __repr__ :

    class Plant(object):
        def __init__(self, color, seeds):
            self.color = color
            self.seeds = seeds
    
    class Fruit(Plant):
        def __init__(self, color, defense):
            self.color = color
            self.seeds = True
            self.defense = defense
    
    class Vehicle(object):
        def __init__(self, num_tires, engine_size, fuel_type):
            self.num_tires = num_tires
            self.engine_size = engine_size
            self.fuel_type = fuel_type
            self.windows = 'up'
    
        def roll_down_windows(self):
            self.windows = 'down'
        def roll_up_windows(self):
            self.windows = 'up'
    
        def __repr__(self):
            print("This is a vehicle. \nIt has {} tires. \nIts engine has {} liters. \nIt runs on {}. \nIt's windows are {}.".format(self.num_tires, self.engine_size, self.fuel_type, self.windows))
    
    class Car(Vehicle):
        def __init__(self, num_tires=4, engine_size, fuel_type):
            self.num_tires = num_tires
            self.engine_size = engine_size
            self.fuel_type = fuel_type
            self.windows = 'up'