返回Python类中的所有类变量值

时间:2017-06-27 21:15:19

标签: python class class-method

我有一个包含所有AWS区域的Python类。我写了一个类方法,它会返回所有区域的列表。是否有更好的方法可以返回所有类变量值,因此我不必像在下面的示例中那样对返回语句中的所有值进行硬编码?

class AwsRegion():
    '''
    Class to define AWS Regions
    '''
    OHIO = 'us-east-2'
    NORTH_VIRGINIA = 'us-east-1'
    NORTH_CALIFORNIA = 'us-west-1'
    OREGON = 'us-west-2'
    MUMBAI = 'ap-south-1'
    SEOUL = 'ap-northeast-2'
    SINGAPORE = 'ap-southeast-1'
    SYDNEY = 'ap-southeast-2'
    TOKYO = 'ap-northeast-1'
    FRANKFURT = 'eu-central-1'
    IRELAND = 'eu-west-1'
    LONDON = 'eu-west-2'
    SAO_PAULO = 'sa-east-1'

    @classmethod
    def all(cls, ):
        return [AwsRegion.OHIO, AwsRegion.NORTH_VIRGINIA, AwsRegion.NORTH_CALIFORNIA, AwsRegion.OREGON, \
            AwsRegion.MUMBAI, AwsRegion.SEOUL, AwsRegion.SINGAPORE, AwsRegion.SYDNEY, AwsRegion.TOKYO, \
            AwsRegion.FRANKFURT, AwsRegion.IRELAND, AwsRegion.LONDON, AwsRegion.SAO_PAULO]

3 个答案:

答案 0 :(得分:3)

作为一般参考,您可以通过以下方式获取任何类的属性。根据您的需求选择:

__dict__

将返回所有可写类属性的字典。这通常是您所需要的。

myObj = MyClass()
attributes = myObj.__dict__

vars()

__dict__的结果相同,但使用此作为最佳做法。

myObj = MyClass()
attributes = dir(myObj)

dir()

将返回所有类属性,包括那些您未制作但继承自object的属性。

myObj = MyClass()
attributes = dir(myObj)

在你的情况下,使用vars()可以正常工作,正如Martijn Pieters在answer中所证明的那样。

答案 1 :(得分:2)

在这种情况下,您可以枚举类的所有大写属性;我使用vars() function来访问类命名空间:

using UnityEngine;
using System.Collections;

public class ControlShip : MonoBehaviour
{

    public float maxVel = 30; // cruise speed
    public float startVel = 5; // speed at the starting point
    public float stopVel = 0.5f; // speed at the destination
    public float accDistance = 20; // acceleration/deceleration distance
    public float factor = 0.25f; // max inclination
    public float turnSpeed = 0.8f; // speed to turn/bank in the target direction
    Vector3 lastPos; // used to calculate current velocity
    Transform baseTarget;
    private Rigidbody _rigidbody;

    void Start()
    {
        _rigidbody = GetComponent<Rigidbody>();
        baseTarget = GameObject.Find("Base").transform;
        lastPos = transform.position;
        StartCoroutine(Fly()); // demo routine
    }
    // calculate bank/turn rotation at Update
    void Update()
    {
        // calculate the displacement since last frame:
        Vector3 dir = transform.position - lastPos;
        lastPos = transform.position; // update lastPos
        float dist = dir.magnitude;
        if (dist > 0.001f)
        { // if moved at least 0.001...
            dir /= dist; // normalize dir...
            float vel = dist / Time.deltaTime; // and calculate current velocity
                                               // bank in the direction of movement according to velocity
            Quaternion bankRot = Quaternion.LookRotation(dir + factor * Vector3.down * vel / maxVel);

            Vector3 rotation = Quaternion.Lerp(transform.rotation, bankRot, turnSpeed * Time.deltaTime).eulerAngles;
            rotation.x = 0;
            transform.rotation = Quaternion.Euler(rotation);
        }
    }

    bool flying = false; // shows when FlyTo is running
                         // coroutine that moves to the specified point:
    IEnumerator FlyTo(Vector3 targetPos)
    {
        flying = true; // flying is true while moving to the target
        Vector3 startPos = transform.position;
        Vector3 dir = targetPos - startPos;
        float distTotal = dir.magnitude;
        dir /= distTotal; // normalize vector dir
                          // calculate accDist even for short distances
        float accDist = Mathf.Min(accDistance, distTotal / 2);
        do
        {
            float dist1 = Vector3.Distance(transform.position, startPos);
            float dist2 = distTotal - dist1;
            float speed = maxVel; // assume cruise speed
            if (dist1 < accDist)
            { // but if in acceleration range...
              // accelerate from startVel to maxVel
                speed = Mathf.Lerp(startVel, maxVel, dist1 / accDist);
            }
            else
            if (dist2 < accDist)
            { // or in deceleration range...
              // fall from maxVel to stopVel
                speed = Mathf.Lerp(stopVel, maxVel, dist2 / accDist);
            }
            // move according to current speed:

            Vector3 pos = Vector3.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);
            pos.y = lastPos.y;
            transform.position = pos;
            yield return 0; // let Unity breathe till next frame
        } while (transform.position != targetPos); // finish when target reached
        flying = false; // shows that flight has finished        
    }
    // example routine: fly to 3 different points in sequence
    IEnumerator Fly()
    {
        Vector3 p0 = baseTarget.position;

        while (true)
        {
            StartCoroutine(FlyTo(p0));
            while (flying)
            {
                yield return 0;
            }
            yield return new WaitForSeconds(5);
        }
    }

    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.name == "Base")
        {

        }
    }
}

演示:

@classmethod
def all(cls):
    return [value for name, value in vars(cls).items() if name.isupper()]

答案 2 :(得分:1)

看起来你可能正在做的是偶然创建Enum类型。

如果您的AwsRegion类仅用于存储这些值(不是许多其他复杂行为),请尝试将其作为Enum的子类。这将为您提供一些不错的方法,而无需自己重新创建它们,并使您的代码更清楚,知道枚举类型是什么。

from enum import Enum

class AwsRegion2(Enum):
    OHIO = 'us-east-2'
    NORTH_VIRGINIA = 'us-east-1'
    NORTH_CALIFORNIA = 'us-west-1'
    OREGON = 'us-west-2'
    MUMBAI = 'ap-south-1'
    SEOUL = 'ap-northeast-2'
    SINGAPORE = 'ap-southeast-1'
    SYDNEY = 'ap-southeast-2'
    TOKYO = 'ap-northeast-1'
    FRANKFURT = 'eu-central-1'
    IRELAND = 'eu-west-1'
    LONDON = 'eu-west-2'
    SAO_PAULO = 'sa-east-1'


print(list(AwsRegion2))