首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >改进Python类“准确性”的设计

改进Python类“准确性”的设计
EN

Code Review用户
提问于 2013-03-14 11:27:14
回答 2查看 164关注 0票数 4

我正在学习Python中的类和方法。

类精度是基于shapely模块的参考多边形和一个或多个分段多边形之间的几个统计值(总共13)的一类。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from numpy import average

#some stat

def ra_or(ref, seg):
    return average([(ref.intersection(s).area/ref.area) for s in seg])


def ra_os(ref, seg):
    return average([(ref.intersection(s).area/s.area) for s in seg])


def sim_size(ref, seg):
return average([(min(ref.area, s.area)/max(ref.area,s.area)) for s in seg])


def AFI(ref,seg):
   return (ref.area - max([s.area for s in seg]))/ref.area

其中ref.intersection(s).areareferencesegmented polygon-i之间的交集区域。

我的课程设计(非常基本,而且可能需要改进)是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Accuracy(object):
    def __init__ (self,ref,seg = None, noData = -9999):
        if seg == None:
            self.area = ref.area
            self.perimeter = ref.length
            self.centroidX = ref.centroid.x
            self.centroidY = ref.centroid.y
            self.data =  [self.centroidX,
                        self.centroidY,
                        self.area,
                        self.perimeter,
                        noData,
                        noData,
                        noData,
                        noData,
                        noData]
        else:
            self.area = ref.area
            self.perimeter = ref.length
            self.centroidX = ref.centroid.x
            self.centroidY = ref.centroid.y
            self.segments = len(seg)
            self.RAor = ra_or(ref,seg)
            self.RAos = ra_os(ref,seg)
            self.SimSize = sim_size(ref,seg)
            self.AFI = AFI(ref,seg)
            self.data = [self.centroidX,
                        self.centroidY,
                        self.area,
                        self.perimeter,
                        self.segments,
                        self.RAor,
                        self.RAos,
                        self.SimSize,
                        self.AFI]

from shapely.geometry import Polygon

p1 = Polygon([(2, 4), (4, 4), (4, 2), (2, 2), (2, 4)])
p2 = Polygon([(0, 3), (3, 3), (3, 0), (0, 0), (0, 3)])

accp1 = Accuracy(p1,[p2])
accp1.data
[3.0, 3.0, 4.0, 8.0, 1, 0.25, 0.1111111111111111, 0.44444444444444442, -1.25]

accp1 = Accuracy(p1)
accp1.data
[3.0, 3.0, 4.0, 8.0, -9999, -9999, -9999, -9999, -9999]
EN

回答 2

Code Review用户

回答已采纳

发布于 2013-03-14 11:55:24

如果计划将四个函数( ra_orra_ossim_sizeAFI )调用到Accuracy之外,那么最好将它们保留为函数。如果只有通过Accuracy才能调用它们,那么就应该使用方法。

类可以帮助组织复杂的代码,但是它们通常不会使代码更快。除非有明显的优势,否则不要使用类--通过继承或多态等等。

如果您想要使用更少内存的更快的代码,请避免在这里使用类。只需为每个属性定义函数即可。

如果您想要“豪华”语法--通过属性引用每个统计数据的能力,那么类就可以了。

如果您计划实例化Accuracy的实例,但并不总是访问所有属性,则不需要在__init__中计算它们。您可以使用属性延迟它们的计算。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 @property
 def area(self):
    return self.ref.area

注意,当您编写accp1.area时,上面的area方法将被调用。注意,在accp1.area之后没有括号。

需要明确的是,使用属性的好处是,Accuracy的每个实例在需要统计属性之前都不会计算它们的所有统计属性。使用属性的缺点是,每次访问属性时都会重新计算它们。如果self.refself.seg发生变化,这可能不是一个不利因素。

此外,您可以使用丹尼斯·奥特卡达的CachedAttribute装饰师.缓存结果,然后只计算属性一次,然后每次只查找一次。

不要对noData (如noData = -9999 )使用任意的值。使用noData = np.nan,或者直接跳过noData并直接使用np.nan

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import numpy as np
from shapely.geometry import Polygon
nan = np.nan

class Accuracy(object):
    def __init__(self, ref, seg=None):
        self.ref = ref
        self.seg = seg

    @property
    def area(self):
        return self.ref.area

    @property
    def perimeter(self):
        return self.ref.length

    @property
    def centroidX(self):
        return self.ref.centroid.x

    @property
    def centroidY(self):
        return self.ref.centroid.y

    @property
    def data(self):
        return [self.centroidX,
                self.centroidY,
                self.area,
                self.perimeter,
                self.segments,
                self.RAor,
                self.RAos,
                self.SimSize,
                self.AFI]

    @property
    def segments(self):
        if self.seg:
            return len(self.seg)
        else:
            return nan

    @property
    def RAor(self):
        if self.seg:
            return np.average(
                [(self.ref.intersection(s).area / self.ref.area) for s in self.seg])
        else:
            return nan

    @property
    def RAos(self):
        if self.seg:
            return np.average(
                [(self.ref.intersection(s).area / s.area) for s in self.seg])
        else:
            return nan

    @property
    def SimSize(self):
        if self.seg:
            return np.average(
                [(min(self.ref.area, s.area) / max(self.ref.area, s.area))
                 for s in self.seg])
        else:
            return nan

    @property
    def AFI(self):
        if self.seg:
            return (self.ref.area - max([s.area for s in self.seg])) / self.ref.area
        else:
            return nan

p1 = Polygon([(2, 4), (4, 4), (4, 2), (2, 2), (2, 4)])
p2 = Polygon([(0, 3), (3, 3), (3, 0), (0, 0), (0, 3)])

accp1 = Accuracy(p1, [p2])
print(accp1.data)
# [3.0, 3.0, 4.0, 8.0, 1, 0.25, 0.1111111111111111, 0.44444444444444442, -1.25]

accp1 = Accuracy(p1)
print(accp1.data)
# [3.0, 3.0, 4.0, 8.0, nan, nan, nan, nan, nan]

下面是如何将数据(作为numpy数组)保存到CSV文件中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
np.savetxt('/tmp/mytest.txt', np.atleast_2d(accp1.data), delimiter=',')

下面是你怎么把它读回来的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
data = np.genfromtxt('/tmp/mytest.txt', dtype=None)
print(data)
# [  3.   3.   4.   8.  nan  nan  nan  nan  nan]
票数 2
EN

Code Review用户

发布于 2013-03-21 16:24:04

我对待这个类的方式和unutbu一样,只是将多边形存储为类的属性,并使用属性和方法进行分析。我认为唯一不同的做法是将其实现为多边形的一个子类,因此任何给定的实例都可以根据需要将自己与任何其他多边形进行比较。我不打算勾勒出细节,但我希望它能像这样工作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sp1 = SmartPolygon([(2, 4), (4, 4), (4, 2), (2, 2), (2, 4)])
sp2 = SmartPolygon([(0, 3), (3, 3), (3, 0), (0, 0), (0, 3)])

sp1.accuracy()
>>> (3.0, 3.0, 4.0, 8.0, nan, nan, nan, nan, nan)

sp1.accuracy(sp2)
>>> (3.0, 3.0, 4.0, 8.0, 1, 0.25, 0.1111111111111111, 0.44444444444444442, -1.25)

其他想法,没有特别的顺序:

作为它自己的类,我个人会使用不同的名称。“‘Accuracy”是你想从对象身上学到的东西的一个方面,但并不能真正代表对象是什么。我将这个类称为类似于PolygonComparison的类,或者称为描述性的,但理想情况下更简洁。我不知道这是否正式是毕达通的,但我认为类是名词,函数/方法是动词,通常这样命名。

你的风格中有一些细微的不一致之处,主要是因为有时在你不该使用的地方加上空格,反之亦然。这些通常不会影响您的代码如何运行,但更多的是可读性、可理解性和可调试性。例如,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def __init__ (self,ref,seg = None, noData = -9999):
# Note spacing:   ^   ^    ^              ^

通常被写成

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def __init__(self, ref, seg=None, noData=-9999):

然后,简单地看一下,该方法有三个参数,其中两个参数具有默认值。我建议看一下PEP 8风格的指南。

最后,请注意,您的__init__方法中有一些冗余:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def __init__(self, ref, seg=None):
    if seg == None:
        self.area = ref.area
        self.perimeter = ref.length
        self.centroidX = ref.centroid.x
        self.centroidY = ref.centroid.y
        ... # etc.
    else:
        self.area = ref.area
        self.perimeter = ref.length
        self.centroidX = ref.centroid.x
        self.centroidY = ref.centroid.y
        ...

可以减少到

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def __init__(self, ref, seg=None):
    self.area = ref.area
    self.perimeter = ref.length
    self.centroidX = ref.centroid.x
    self.centroidY = ref.centroid.y

    # Typically you check if something *is* None, rather than *equals* None.
    if seg is None:
        ...
    else:
        ...
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/23929

复制
相关文章
父进程退出时如何确保子进程退出?
子进程退出的时候,父进程能够收到子进程退出的信号,便于管理,但是有时候又需要在父进程退出的时候,子进程也退出,该怎么办呢?
编程珠玑
2019/09/02
12.4K0
解决Mac终端退出时的不爽
从Fedora切换到Linux下,有很多不适应,与其说不适应不如说不爽,其中一个就是今天要说的终端输入exit的问题.在Linux发行版中,输入exit会推出当前窗口,而Mac居然不是,弄出来一个特别脑残的Process Completed,中文版提示大概是提示进程已完成. 然后什么也不能做,只能关闭.真心有点搞不懂这么设计的用意是什么.
技术小黑屋
2018/09/04
1.9K0
解决Mac终端退出时的不爽
nohup 退出终端不退出任务
你是否遇到过远程在linux 下运行node,python 监听脚本,程序跑起来以后,退出了终端,当你再登录时发现原先的任务已经退出了,怎么办?怎么才能在终端退出的情况下,让任务正常运行。
酒馆丁老师
2020/09/08
4.9K0
如何防止PHP进程异常退出(进程被杀)?
通常,在cli下运行的常驻后台PHP进程,可能异常退出,比如php执行过程中出现的致命错误,或被 kill 命令手动杀死等。如下面的php代码:
猿哥
2019/07/25
2.5K0
如何在 centos 终端中退出一个程序
在 Linux 中,你可以使用 Ctrl+C 键来中止终端中的运行程序。这对 Ubuntu 和其他 Linux 发行版都适用。
用户4988085
2021/09/17
4.6K0
cmd中如何退出Python
cmd中如何退出Python      (1)在命令行上输入exit()      (2)在命令行上输入quit() 好像还有一种方法是在命令行上输入Ctrl+Z,再按回车,但是我一直成功不了,
py3study
2020/01/03
2.2K0
cmd中如何退出Python
在 Linux 终端中退出一个程序的操作命令
在 Linux 中,你可以使用 Ctrl+C 键来中止终端中的运行程序。这对 Ubuntu 和其他 Linux 发行版都适用。
用户9105998
2021/11/22
5.2K0
PHP内存分配超过限制的退出流程
我们知道,在PHP的世界里,如果我们要申请一块内存 ,但是没有申请到,那么就会导致fatal级别的错误。我们来测试下:
桶哥
2020/07/15
1.7K0
Node 脚本遭遇异常时如何安全退出
一个 Node 相关的项目中,总是少不了跑脚本。跑一个脚本拉取配置、处理一些数据以及定时任务更是家常便饭。
山月
2020/08/28
1.8K0
当Python退出时,为什么不清除所有分配的内存?
在讨论为什么 Python 在退出时不清除所有分配的内存之前,我们需要了解 Python 的内存管理机制。Python 使用一种称为 引用计数 的垃圾回收机制来管理内存。在这种机制下,每个对象都有一个引用计数器,记录着当前有多少个引用指向该对象。当引用计数器为 0 时,对象将被销毁,内存得以释放。然而,在 Python 退出时,并不会清除所有分配的内存。本文将探讨这个问题,并给出相应的解释。
疯狂的KK
2023/08/05
1.2K0
当Python退出时,为什么不清除所有分配的内存?
如何退出Vim
阅读本文大概需要 1 分钟 退出Vim: 如果您处于编辑模式,请先<Esc>按键。 然后输入:wq + <Enter>保存并退出。 你想要的很少见,但是如果没有保存就退出,你就可以跑了 :q! + <Enter> 结束 鉴于您处于命令模式: :wqa将写入,退出所有缓冲区(如果您有多个缓冲区) :x 也将保存并退出 :ex 如上 ZZ 将保存并退出 ZQ 将退出 :1,5wq将只保存第1到第5行并退出 还有更多。多很多。感兴趣吗?你学会了吗?
硬核编程
2019/09/25
5.3K0
python中如何退出多层循环
 2、使用函数配合return关键字 实现跳出循环(在函数内部只要执行完return语句 则直接退出函数)
py3study
2020/01/20
2.2K0
[UWP]在应用退出时弹出确认提示框
在应用退出时(点击右上角的关闭按钮)弹出一个确认按钮可以说是一个最常见的操作了,例如记事本的“你是否保存”:
dino.c
2019/12/12
3.9K0
[UWP]在应用退出时弹出确认提示框
centos 如何退出vim
点击ESC进入“正常模式”,然后输入“:”,进入“命令模式”。此时屏幕的下方会出现一个冒号,你可以输入以下命令,并按“ENTER”执行:
全栈程序员站长
2022/08/31
3.1K0
linux vi命令 退出不保存,linux vi保存退出命令(如何退出vi)
若用户真的希望用文件的当前内容替换newfile中原有内容,可使用命令 :q! Vi放弃所作修改而直接退到shell下,则Vi在显示窗口的状态行给出提示信息: File exists (use ! to override) 此时, 在末行模式下,。
全栈程序员站长
2022/11/11
27.3K0
如何退出Vi或Vim编辑器「建议收藏」
The vi editor is confusing if you’re not used to it. It takes a secret handshake to escape this application if you’ve stumbled into it. Here’s how to quit vi or vim on Linux, macOS, or any other Unix-like system.
全栈程序员站长
2022/11/11
5K0
如何退出Vi或Vim编辑器「建议收藏」
Python 循环的继续与退出 continue and break
循环的继续与退出 continue and break continue语法 功能 循环遇到continue将停止本次数据循环 , 进入下一次循环 用法 while bool: continue for item in iterable: continue print(item) 参数 continue属于语法, 不需要加 ( )即可执行 无参数 返回值 continue是语法,没有返回值 break语法 功能 使循环正常停止循环(遍历) 这时如果循环配合了Else语句,else语句将不执行 用法
Zkeq
2022/05/18
9460
git 中的退出
链接:https://pan.baidu.com/s/1Zl7EEZY-kfMzSDGOeGgblw 提取码:ec35
李才哥
2019/08/12
3.8K0
git 中的退出
python中break退出for循环 和continue退出for循环
其实break和continue退出for循环的用法和退出while的用法是一样的。break,当某些条件成立退出循环,后面代码不执行,终止整个循环;continue,当某些条件成立终止当前循环继而执行下次循环。下面用2个代码示例来看看一下怎么使用以及执行结果。
python自学网
2022/03/28
2.5K0
python中break退出for循环 和continue退出for循环
当被监测的进程异常退出后,如何启动 - WGCLOUD
那么我们如何在进程退出后,怎么启动进程呢?以下三种方式均为WGCLOUD提供的功能
那年十八
2022/10/22
1.6K0
当被监测的进程异常退出后,如何启动 - WGCLOUD

相似问题

如何恢复ext3 fs上已删除的文件

50

在ubuntu8.04上升级ext3 fs

10

如何从损坏的ext3分区恢复数据?

30

EXT3 3-fs错误(设备dm-10)

10

在挂载上禁止EXT3 3-fs警告

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文