如何在不创建实例的情况下有选择地访问类方法

时间:2019-07-18 20:00:53

标签: python class instance

我是python的新手,对OOP有所了解。我正在创建一个类以对数据执行一些基本方法,但理想情况下,我希望将这些类方法作为常规函数访问,而不必先创建实例。

我为MyMethod设置了以下代码,其中包含单个方法'clip_sphere',该方法将xyz坐标作为数组,并返回位于以'center'为中心,半径为'radius'的球体内的坐标

import numpy as np

class MyMethod:

    def __init__(self,xyz):
        self.xyz = xyz

    def clip_sphere(self, center, radius):

        self.xyz = self.xyz - np.array(center).reshape(1,-1)
        r = (np.sum(self.xyz**2, axis = 1))**0.5
        idx = r < radius

        xyz_clip = self.xyz[idx,:]
        self.clip = xyz_clip

        return xyz_clip

我想做的是能够以两种方式运行剪辑球体,以1:凋谢。

C = MyMethod(xyz)
xyz_clip = C.clip_sphere(center =[0,0,0],radius = 2)

或简单地通过将其作为函数来调用:

xyz_clip = clip_sphere(xyz,center =[0,0,0],radius = 2)

最好不重写为普通函数。这可能与某些装饰器有关吗?甚至根本不可能。

编辑:看了一些答案之后,我想我想问的是如何获得像numpy reshape这样的函数。因为两者都允许这样的语句:

a = np.reshape(np.array([1,2,3]),[3,1]) 

哪个像一个函数 以及:

 a = np.array([1,2,3]) 
 a.reshape([3,1])

就像一个类方法

4 个答案:

答案 0 :(得分:3)

它是内置的-您所需要做的就是从类的名称空间获取函数:

C = MyMethod(xyz)
xyz_clip = MyMethod.clip_sphere(C, center =[0,0,0], radius = 2)

但是,这仍然需要您具有该类的实例。问题在于编写代码是为了在特定的命名对象(名为xyz的一个对象中找到self等属性。 (除约定外,Python中的名称self没什么特别的。)

如果确实需要使用xyz来实现此功能,那么明智的方法是编写一个简单的函数来处理它:

# At top level
def clip(xyz, center, radius):
    xyz -= np.array(center).reshape(1,-1)
    r = (np.sum(xyz**2, axis = 1))**0.5
    idx = r < radius
    return xyz[idx,:]

然后为避免重复代码,可以使用此代码来实现该方法:

# inside the class
def clip_sphere(self, center, radius):
    # This part of the process needs to be repeated, because the
    # `xyz` variable during the `clip` call is a separate name.
    # However, you should consider whether you *actually* want to modify
    # the object's `self.xyz` as a part of this process. My guess is you do not.
    self.xyz -= np.array(center).reshape(1,-1)
    self.clip = clip(self.xyz, center, radius) # uses the top-level `clip`.

答案 1 :(得分:0)

看起来您想要一个独立的函数,而不是一个类/对象:

def clip_sphere(xyz, center, radius):

    xyz = xyz - np.array(center).reshape(1,-1)
    r = (np.sum(xyz**2, axis = 1))**0.5
    idx = r < radius

    xyz_clip = xyz[idx,:]
    clip = xyz_clip

    return xyz_clip

答案 2 :(得分:0)

您可以创建一个名为clip_sphere()的全局函数:

def clip_sphere(xyz, center, radius):
   return MyMethod(xyz).clip_sphere(center, radius)

但是这样做使我想知道为什么您根本不需要上课。据我所知,您正在此处进行操作,创建一个Sphere类可能更有意义。显然,这是一个具有以下属性的对象:radiuscenter。然后,您可以添加clip()方法来执行所需的操作:

class Sphere:
   def __init__(center, radius):
      self.center = center
      self.radius = radius

   def clip(x, y, z):
      # code goes here

编辑响应:

  

查看了一些答案之后,我想我想问的是如何获得像numpy reshape这样的函数。因为两者都允许这样的语句:

a = np.reshape(np.array([1,2,3]),[3,1])
     

哪个功能像一个函数?

a = np.array([1,2,3]) 
a.reshape([3,1])

这是两个不同的功能,而不是调用同一功能的两种不同方式。

答案 3 :(得分:0)

请记住描述符的工作原理,您可以对正确编写的clip_sphere方法进行少量修改,使您可以将方法作为方法运行,也可以作为接受坐标为classmethod的方法运行第一个参数:

def clip_sphere(self, center, radius):
    xyz = self.xyz if isinstance(self, __class__) else self
    xyz -= np.array(center).reshape(1,-1)
    r = (np.sum(self.xyz**2, axis = 1))**0.5
    idx = r < radius
    xyz_clip = self.xyz[idx,:]
    if isinstance(self, __class__):
        self.clip = xyz_clip
        self.xyz = xyz
    return xyz_clip

您可以将其作为方法调用:

>>> xyz = ...
>>> MyMethod().clip_sphere(...)

或作为classmethod

>>> MyMethod.clip_sphere(xyz, ...)