我有一个包含所有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]
答案 0 :(得分:3)
作为一般参考,您可以通过以下方式获取任何类的属性。根据您的需求选择:
将返回所有可写类属性的字典。这通常是您所需要的。
myObj = MyClass()
attributes = myObj.__dict__
与__dict__
的结果相同,但使用此作为最佳做法。
myObj = MyClass()
attributes = dir(myObj)
将返回所有类属性,包括那些您未制作但继承自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))