简体   繁体   中英

Writing a Vector (Math) Class in Python

Here is my Vector class

class Vector:
   def __init__(self, *v):
        self.v = v

It works great for things such as:

v = Vector(1, 1, 1)

where self.v prints out a list

How would I change it so that:

v = Vector([1, 1, 1]) 

it prints out a list. Currently, it prints out a list within a list.

from collections import Iterable

class Vector:
    def __init__(self, *v):
        if len(v) == 1 and isinstance(v[0], Iterable) and not isinstance(v[0], str):
            # iterable (but not string) - cast to list
            self.v = list(v[0])
        else:
            self.v = v

Since *v will give multiple positional argument, if you don't want to loose this property you can check it the length of v is 1 then just assign the first item to self.v :

class Vector:
   def __init__(self, *v):
        self.v = v[0] if len(v) == 1 else v 

Also note that this expression might raise some exceptions based on the type of v So as a more pythonic and safer way you better to use a try-except expression to handle the exceptions.

from collections.abc import Iterable # In python 2.x collections import Iterable

    class Vector:
       def __init__(self, *v):
            try:
                self.length = len(v)
            except TypeError:
                self.v = v
            else:
                 if isinstance(v, Iterable):
                     self.v = v[0] if self.length == 1 else v
                 else:
                     self.v = v

If you want your class to behave differently when it's passed a single list than when it's passed multiple numbers, you need to put some conditional logic in your __init__ method. Something like this might work (though there are other ways you could do the checking):

def __init__(self, *v):
    if len(v) == 1:
        v = v[0]

    self.v = v

Obviously this won't work as expected for a 1-dimensional Vector ( v will be set to the single scalar value, rather than a 1-valued list). You could probably use isinstance to make sure the single value is in fact a list or tuple if you want, but I suspect there would still be awkward corner cases you'd get wrong.

A better approach may be to change the code that wants to pass in a list. If instead of Vector([1,1,1]) , you did Vector(*[1,1,1]) , your existing code would work just fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM