简体   繁体   中英

Example of how to properly define a class in python

I have defined a function as such:

def quicksort(points):
    if len(points) < 2: return points
    smaller,equal,larger = [], [], []
    pivot_angle = find_polar_angle(random.randint(0, len(points) - 1))
    for pt in points:
        pt_angle = find_polar_angle(pt)
        if pt_angle < pivot_angle:
            smaller.append(pt)
        elif pt_angle == pivot_angle: 
            equal.append(pt)
        else:
            larger.append(pt)
    return quicksort(smaller) + sorted(equal, key = find_dist) + quicksort(larger)

Now, I want to change my code - which btw is an implementation of the Graham Scan Algorithm - into an object oriented code. So I went ahead and declared a class in a file MyClasses.py:

from MyFunctions import find_anchor, find_polar_angle, find_dist, find_det, quicksort, graham_scan

class Cluster:
    def __init__(self):
        self.members = []
        self.hull = []
        self.anchor = None

        self.find_anchor = find_anchor
        self.find_polar_angle = find_polar_angle
        self.find_dist = find_dist
        self.find_det = find_det
        self.quicksort = quicksort
        self.graham_scan = graham_scan

But of course I have to change my functions as well. I don't want to list all the functions here, that's why I stay with the quicksort function as an example. This is where I struggle a lot, since I don't know the python syntax well enough to be sure about what I am doing here. This is my revised form of quicksort :

def quicksort(self, points):
    if len(points) < 2: return points
    smaller,equal,larger = [], [], []
    pivot_angle = self.find_polar_angle(self, random.randint(0, len(self.members) - 1))
    for pt in points:
        pt_angle = self.find_polar_angle(self, pt)
        if pt_angle < pivot_angle:
            smaller.append(pt)
        elif pt_angle == pivot_angle: 
            equal.append(pt)
        else:
            larger.append(pt)
    return self.quicksort(self, smaller) + sorted(self, equal, key = self.find_dist) + self.quicksort(self, larger)

Here's the thing: This function is recursive! So I need it to take smaller, equal and larger as arguments. Later, another function graham_scan is going to call this function as such:

self.members = self.quicksort(self, self.members)

I know there are probably many mistakes in here. That's why I'm asking: Is this last expression a valid expression? I mean I am changing a class-variable ( self.members ) but I do so not by directly changing it, but by assigning it the return value of quicksort . Anyways, help is very much appreciated!

To make an existing function as a new property of a new class, try this:

def quicksort():
    pass # your custom logic

class Cluster:
    def __init__(self):
        self.members = []
        self.quicksort = quicksort
        # more properties

Python has quite a different syntax to C++ or Java.

To say about the second question, all the variables used in quicksort function body are only available in that function only.

About second question. All members of classes are PUBLIC in python. By convention you can add "_" and "__" in front of the names for protected and private respectfully. BUT this does NOT prevent you from accessing them, it just means that you (or whoever reading the code) should not misuse them. Although, __variable must be accessed with following syntax outside of class:

class Square:

    def __init__(self, x):
        self.__x = x

    def get_surface(self):
        return self.__x **2


>>> square1 = Square(5)
>>> print(square1.get_surface())
>>> 25
>>> square1._Square__x = 10
>>> print(square1.get_surface())
>>> 100


>>> square1.__x
>>> **AttributeError: 'Square' object has no attribute '__x'**

Or it will raise AttributeError. Hope this helps

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