[python] 문자열로 그 이름을 가진 속성에 접근하기

Key-Value coding in Python

파이썬에서 키-밸류코딩(문자열을 통해 특정 멤버변수 혹은 로컬변수에 접근)하는 방법에 대해 알아보자.

전역변수 혹은 지역 변수에 대해 문자열로 접근하기

globals() , locals() 함수는 각각 전역변수와 지역변수의 키-값 쌍을 사전으로 반환한다. 따라서 locals()['someVar']라고 쓰면 지역변수 someVar의 값을 구할 수 있다. 이 방법은 파이썬2, 파이썬3에서 공통적으로 사용 가능하다.

객체의 속성값(멤버)에 대해 문자열로 접근하기

getattr(), setattr()을 사용하면 특정한 객체 내부의 값에 대해 문자열로 접근할 수 있다.

호출 가능한 속성인지 확인하기

파이썬에서는 객체의 속성에 대해 객체인지, 값인지 (파이썬은 상수도 객체로 인식한다.) 혹은 함수인지 (파이썬은 함수도 객체로 인식한다.) 아리송할 때가 있다. 이 때는 callable()함수를 사용해서 해당 객체를 넣어주면 호출 가능한지 아닌지 알 수 있게 된다. (호출 가능한 속성은 내부적으로 다시 call 함수가 정의되어 있다. 클래스를 정의할 때도 해당 클래스의 call 함수를 정의해두면 클래스 이름을 함수처럼 사용할 수 있다.

def viewAttrs(obj):
    for ar in dir(obj):
        if callable(getattr(obj,ar)):
            print "Callable >> %s : %s\n\n" % (ar, getattr(obj,ar).__doc__)
        else:
            print "Property >> %s : %s\n\n" % (ar, getattr(obj,ar).__doc__)

위 코드는 특정 객체를 받아, 해당 객체의 모든 속성을 조사하여 실행 가능한지 여부와 함께, 해당 속성의 문서화된 정보를 표시해준다. 참고로 hasattr()도 있고, 이는 당연히 객체가 주어진 이름을 갖는 속성을 가지고 있는지 알아내는 함수이다.

callable()과 조합하면 어떤 객체가 어떤 메소드(실행가능한 속성)를 가지고 있는지를 미리 확인한 후 호출할 수 있게 된다.

사실 중요한 건 ‘키-패스(keypath)’를 통해서 문자열만으로 객체의 속성 아래의 속성… 뭐 예를 들자면 someObjc.property.key.anotherKey… 이런 식으로 접근하는 것은 getattr()함수로는 불가능하다. (그렇지만 이런 함수는 충분히 만들 수 있기는 하다.) 게다가 이미 어떤 능력자가 키패스로 리스트나 사전의 값까지 참조할 수 있는 함수를 만들어서 공개해 두기도 하였다. (한국분이다 덜덜덜)

부록으로 파이썬 2.7의 전체 내장 함수를 살펴보자. (viewAttrs(__builtins__)) 나도 잘 몰랐던 함수들이 수두룩하게 쏟아진다.

Callable : ArithmeticError > Base class for arithmetic errors.

Callable : AssertionError > Assertion failed.

Callable : AttributeError > Attribute not found.

Callable : BaseException > Common base class for all exceptions

Callable : BufferError > Buffer error.

Callable : BytesWarning > Base class for warnings about bytes and buffer related problems, mostly
related to conversion from str or comparing to str.

Callable : DeprecationWarning > Base class for warnings about deprecated features.

Callable : EOFError > Read beyond end of file.

Property : Ellipsis > None

Callable : EnvironmentError > Base class for I/O related errors.

Callable : Exception > Common base class for all non-exit exceptions.

Property : False > bool(x) -> bool

Returns True when the argument x is true, False otherwise.
The builtins True and False are the only two instances of the class bool.
The class bool is a subclass of the class int, and cannot be subclassed.

Callable : FloatingPointError > Floating point operation failed.

Callable : FutureWarning > Base class for warnings about constructs that will change semantically
in the future.

Callable : GeneratorExit > Request that a generator exit.

Callable : IOError > I/O operation failed.

Callable : ImportError > Import can't find module, or can't find name in module.

Callable : ImportWarning > Base class for warnings about probable mistakes in module imports

Callable : IndentationError > Improper indentation.

Callable : IndexError > Sequence index out of range.

Callable : KeyError > Mapping key not found.

Callable : KeyboardInterrupt > Program interrupted by user.

Callable : LookupError > Base class for lookup errors.

Callable : MemoryError > Out of memory.

Callable : NameError > Name not found globally.

Property : None > None

Property : NotImplemented > None

Callable : NotImplementedError > Method or function hasn't been implemented yet.

Callable : OSError > OS system call failed.

Callable : OverflowError > Result too large to be represented.

Callable : PendingDeprecationWarning > Base class for warnings about features which will be deprecated
in the future.

Callable : ReferenceError > Weak ref proxy used after referent went away.

Callable : RuntimeError > Unspecified run-time error.

Callable : RuntimeWarning > Base class for warnings about dubious runtime behavior.

Callable : StandardError > Base class for all standard Python exceptions that do not represent
interpreter exiting.

Callable : StopIteration > Signal the end from iterator.next().

Callable : SyntaxError > Invalid syntax.

Callable : SyntaxWarning > Base class for warnings about dubious syntax.

Callable : SystemError > Internal error in the Python interpreter.

Please report this to the Python maintainer, along with the traceback,
the Python version, and the hardware/OS platform and version.

Callable : SystemExit > Request to exit from the interpreter.

Callable : TabError > Improper mixture of spaces and tabs.

Property : True > bool(x) -> bool

Returns True when the argument x is true, False otherwise.
The builtins True and False are the only two instances of the class bool.
The class bool is a subclass of the class int, and cannot be subclassed.

Callable : TypeError > Inappropriate argument type.

Callable : UnboundLocalError > Local name referenced but not bound to a value.

Callable : UnicodeDecodeError > Unicode decoding error.

Callable : UnicodeEncodeError > Unicode encoding error.

Callable : UnicodeError > Unicode related error.

Callable : UnicodeTranslateError > Unicode translation error.

Callable : UnicodeWarning > Base class for warnings about Unicode related problems, mostly
related to conversion problems.

Callable : UserWarning > Base class for warnings generated by user code.

Callable : ValueError > Inappropriate argument value (of correct type).

Callable : Warning > Base class for warning categories.

Callable : ZeroDivisionError > Second argument to a division or modulo operation was zero.

Property : _ > list() -> new empty list
list(iterable) -> new list initialized from iterable's items

Property : __debug__ > bool(x) -> bool

Returns True when the argument x is true, False otherwise.
The builtins True and False are the only two instances of the class bool.
The class bool is a subclass of the class int, and cannot be subclassed.

Property : __doc__ > str(object) -> string

Return a nice string representation of the object.
If the argument is a string, the return value is the same object.

Callable : __import__ > __import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module

Import a module.  The globals are only used to determine the context;
they are not modified.  The locals are currently unused.  The fromlist
should be a list of names to emulate ``from name import ...'', or an
empty list to emulate ``import name''.
When importing a module from a package, note that __import__('A.B', ...)
returns package A when fromlist is empty, but its submodule B when
fromlist is not empty.  Level is used to determine whether to perform 
absolute or relative imports.  -1 is the original strategy of attempting
both absolute and relative imports, 0 is absolute, a positive number
is the number of parent directories to search relative to the current module.

Property : __name__ > str(object) -> string

Return a nice string representation of the object.
If the argument is a string, the return value is the same object.

Property : __package__ > None

Callable : abs > abs(number) -> number

Return the absolute value of the argument.

Callable : all > all(iterable) -> bool

Return True if bool(x) is True for all values x in the iterable.

Callable : any > any(iterable) -> bool

Return True if bool(x) is True for any x in the iterable.

Callable : apply > apply(object[, args[, kwargs]]) -> value

Call a callable object with positional arguments taken from the tuple args,
and keyword arguments taken from the optional dictionary kwargs.
Note that classes are callable, as are instances with a __call__() method.

Deprecated since release 2.3. Instead, use the extended call syntax:
    function(*args, **keywords).

Callable : basestring > Type basestring cannot be instantiated; it is the base for str and unicode.

Callable : bin > bin(number) -> string

Return the binary representation of an integer or long integer.

Callable : bool > bool(x) -> bool

Returns True when the argument x is true, False otherwise.
The builtins True and False are the only two instances of the class bool.
The class bool is a subclass of the class int, and cannot be subclassed.

Callable : buffer > buffer(object [, offset[, size]])

Create a new buffer object which references the given object.
The buffer will reference a slice of the target object from the
start of the object (or at the specified offset). The slice will
extend to the end of the target object (or with the specified size).

Callable : bytearray > bytearray(iterable_of_ints) -> bytearray.
bytearray(string, encoding[, errors]) -> bytearray.
bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.
bytearray(memory_view) -> bytearray.

Construct an mutable bytearray object from:
  - an iterable yielding integers in range(256)
  - a text string encoded using the specified encoding
  - a bytes or a bytearray object
  - any object implementing the buffer API.

bytearray(int) -> bytearray.

Construct a zero-initialized bytearray of the given length.

Callable : bytes > str(object) -> string

Return a nice string representation of the object.
If the argument is a string, the return value is the same object.

Callable : callable > callable(object) -> bool

Return whether the object is callable (i.e., some kind of function).
Note that classes are callable, as are instances with a __call__() method.

Callable : chr > chr(i) -> character

Return a string of one character with ordinal i; 0 <= i < 256.

Callable : classmethod > classmethod(function) -> method

Convert a function to be a class method.

A class method receives the class as implicit first argument,
just like an instance method receives the instance.
To declare a class method, use this idiom:

  class C:
      def f(cls, arg1, arg2, ...): ...
      f = classmethod(f)

It can be called either on the class (e.g. C.f()) or on an instance
(e.g. C().f()).  The instance is ignored except for its class.
If a class method is called for a derived class, the derived class
object is passed as the implied first argument.

Class methods are different than C++ or Java static methods.
If you want those, see the staticmethod builtin.

Callable : cmp > cmp(x, y) -> integer

Return negative if x<y, zero if x==y, positive if x>y.

Callable : coerce > coerce(x, y) -> (x1, y1)

Return a tuple consisting of the two numeric arguments converted to
a common type, using the same rules as used by arithmetic operations.
If coercion is not possible, raise TypeError.

Callable : compile > compile(source, filename, mode[, flags[, dont_inherit]]) -> code object

Compile the source string (a Python module, statement or expression)
into a code object that can be executed by the exec statement or eval().
The filename will be used for run-time error messages.
The mode must be 'exec' to compile a module, 'single' to compile a
single (interactive) statement, or 'eval' to compile an expression.
The flags argument, if present, controls which future statements influence
the compilation of the code.
The dont_inherit argument, if non-zero, stops the compilation inheriting
the effects of any future statements in effect in the code calling
compile; if absent or zero these statements do influence the compilation,
in addition to any features explicitly specified.

Callable : complex > complex(real[, imag]) -> complex number

Create a complex number from a real part and an optional imaginary part.
This is equivalent to (real + imag*1j) where imag defaults to 0.

Callable : copyright > interactive prompt objects for printing the license text, a list of
    contributors and the copyright notice.

Callable : credits > interactive prompt objects for printing the license text, a list of
    contributors and the copyright notice.

Callable : delattr > delattr(object, name)

Delete a named attribute on an object; delattr(x, 'y') is equivalent to
``del x.y''.

Callable : dict > dict() -> new empty dictionary
dict(mapping) -> new dictionary initialized from a mapping object's
    (key, value) pairs
dict(iterable) -> new dictionary initialized as if via:
    d = {}
    for k, v in iterable:
        d[k] = v
dict(**kwargs) -> new dictionary initialized with the name=value pairs
    in the keyword argument list.  For example:  dict(one=1, two=2)

Callable : dir > dir([object]) -> list of strings

If called without an argument, return the names in the current scope.
Else, return an alphabetized list of names comprising (some of) the attributes
of the given object, and of attributes reachable from it.
If the object supplies a method named __dir__, it will be used; otherwise
the default dir() logic is used and returns:
  for a module object: the module's attributes.
  for a class object:  its attributes, and recursively the attributes
    of its bases.
  for any other object: its attributes, its class's attributes, and
    recursively the attributes of its class's base classes.

Callable : divmod > divmod(x, y) -> (div, mod)

Return the tuple ((x-x%y)/y, x%y).  Invariant: div*y + mod == x.

Callable : enumerate > enumerate(iterable[, start]) -> iterator for index, value of iterable

Return an enumerate object.  iterable must be another object that supports
iteration.  The enumerate object yields pairs containing a count (from
start, which defaults to zero) and a value yielded by the iterable argument.
enumerate is useful for obtaining an indexed list:
    (0, seq[0]), (1, seq[1]), (2, seq[2]), ...

Callable : eval > eval(source[, globals[, locals]]) -> value

Evaluate the source in the context of globals and locals.
The source may be a string representing a Python expression
or a code object as returned by compile().
The globals must be a dictionary and locals can be any mapping,
defaulting to the current globals and locals.
If only globals is given, locals defaults to it.

Callable : execfile > execfile(filename[, globals[, locals]])

Read and execute a Python script from a file.
The globals and locals are dictionaries, defaulting to the current
globals and locals.  If only globals is given, locals defaults to it.

Callable : exit > None

Callable : file > file(name[, mode[, buffering]]) -> file object

Open a file.  The mode can be 'r', 'w' or 'a' for reading (default),
writing or appending.  The file will be created if it doesn't exist
when opened for writing or appending; it will be truncated when
opened for writing.  Add a 'b' to the mode for binary files.
Add a '+' to the mode to allow simultaneous reading and writing.
If the buffering argument is given, 0 means unbuffered, 1 means line
buffered, and larger numbers specify the buffer size.  The preferred way
to open a file is with the builtin open() function.
Add a 'U' to mode to open the file for input with universal newline
support.  Any line ending in the input file will be seen as a '\n'
in Python.  Also, a file so opened gains the attribute 'newlines';
the value for this attribute is one of None (no newline read yet),
'\r', '\n', '\r\n' or a tuple containing all the newline types seen.

'U' cannot be combined with 'w' or '+' mode.

Callable : filter > filter(function or None, sequence) -> list, tuple, or string

Return those items of sequence for which function(item) is true.  If
function is None, return the items that are true.  If sequence is a tuple
or string, return the same type, else return a list.

Callable : float > float(x) -> floating point number

Convert a string or number to a floating point number, if possible.

Callable : format > format(value[, format_spec]) -> string

Returns value.__format__(format_spec)
format_spec defaults to ""

Callable : frozenset > frozenset() -> empty frozenset object
frozenset(iterable) -> frozenset object

Build an immutable unordered collection of unique elements.

Callable : getattr > getattr(object, name[, default]) -> value

Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case.

Callable : globals > globals() -> dictionary

Return the dictionary containing the current scope's global variables.

Callable : hasattr > hasattr(object, name) -> bool

Return whether the object has an attribute with the given name.
(This is done by calling getattr(object, name) and catching exceptions.)

Callable : hash > hash(object) -> integer

Return a hash value for the object.  Two objects with the same value have
the same hash value.  The reverse is not necessarily true, but likely.

Callable : help > Define the builtin 'help'.
    This is a wrapper around pydoc.help (with a twist).

Callable : hex > hex(number) -> string

Return the hexadecimal representation of an integer or long integer.

Callable : id > id(object) -> integer

Return the identity of an object.  This is guaranteed to be unique among
simultaneously existing objects.  (Hint: it's the object's memory address.)

Callable : input > input([prompt]) -> value

Equivalent to eval(raw_input(prompt)).

Callable : int > int(x[, base]) -> integer

Convert a string or number to an integer, if possible.  A floating point
argument will be truncated towards zero (this does not include a string
representation of a floating point number!)  When converting a string, use
the optional base.  It is an error to supply a base when converting a
non-string.  If base is zero, the proper base is guessed based on the
string content.  If the argument is outside the integer range a
long object will be returned instead.

Callable : intern > intern(string) -> string

``Intern'' the given string.  This enters the string in the (global)
table of interned strings whose purpose is to speed up dictionary lookups.
Return the string itself or the previously interned string object with the
same value.

Callable : isinstance > isinstance(object, class-or-type-or-tuple) -> bool

Return whether an object is an instance of a class or of a subclass thereof.
With a type as second argument, return whether that is the object's type.
The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for
isinstance(x, A) or isinstance(x, B) or ... (etc.).

Callable : issubclass > issubclass(C, B) -> bool

Return whether class C is a subclass (i.e., a derived class) of class B.
When using a tuple as the second argument issubclass(X, (A, B, ...)),
is a shortcut for issubclass(X, A) or issubclass(X, B) or ... (etc.).

Callable : iter > iter(collection) -> iterator
iter(callable, sentinel) -> iterator

Get an iterator from an object.  In the first form, the argument must
supply its own iterator, or be a sequence.
In the second form, the callable is called until it returns the sentinel.

Callable : len > len(object) -> integer

Return the number of items of a sequence or mapping.

Callable : license > interactive prompt objects for printing the license text, a list of
    contributors and the copyright notice.

Callable : list > list() -> new empty list
list(iterable) -> new list initialized from iterable's items

Callable : locals > locals() -> dictionary

Update and return a dictionary containing the current scope's local variables.

Callable : long > long(x[, base]) -> integer

Convert a string or number to a long integer, if possible.  A floating
point argument will be truncated towards zero (this does not include a
string representation of a floating point number!)  When converting a
string, use the optional base.  It is an error to supply a base when
converting a non-string.

Callable : map > map(function, sequence[, sequence, ...]) -> list

Return a list of the results of applying the function to the items of
the argument sequence(s).  If more than one sequence is given, the
function is called with an argument list consisting of the corresponding
item of each sequence, substituting None for missing values when not all
sequences have the same length.  If the function is None, return a list of
the items of the sequence (or a list of tuples if more than one sequence).

Callable : max > max(iterable[, key=func]) -> value
max(a, b, c, ...[, key=func]) -> value

With a single iterable argument, return its largest item.
With two or more arguments, return the largest argument.

Callable : memoryview > memoryview(object)

Create a new memoryview object which references the given object.

Callable : min > min(iterable[, key=func]) -> value
min(a, b, c, ...[, key=func]) -> value

With a single iterable argument, return its smallest item.
With two or more arguments, return the smallest argument.

Callable : next > next(iterator[, default])

Return the next item from the iterator. If default is given and the iterator
is exhausted, it is returned instead of raising StopIteration.

Callable : object > The most base type

Callable : oct > oct(number) -> string

Return the octal representation of an integer or long integer.

Callable : open > open(name[, mode[, buffering]]) -> file object

Open a file using the file() type, returns a file object.  This is the
preferred way to open a file.  See file.__doc__ for further information.

Callable : ord > ord(c) -> integer

Return the integer ordinal of a one-character string.

Callable : pow > pow(x, y[, z]) -> number

With two arguments, equivalent to x**y.  With three arguments,
equivalent to (x**y) % z, but may be more efficient (e.g. for longs).

Callable : print > print(value, ..., sep=' ', end='\n', file=sys.stdout)

Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep:  string inserted between values, default a space.
end:  string appended after the last value, default a newline.

Callable : property > property(fget=None, fset=None, fdel=None, doc=None) -> property attribute

fget is a function to be used for getting an attribute value, and likewise
fset is a function for setting, and fdel a function for del'ing, an
attribute.  Typical use is to define a managed attribute x:
class C(object):
    def getx(self): return self._x
    def setx(self, value): self._x = value
    def delx(self): del self._x
    x = property(getx, setx, delx, "I'm the 'x' property.")

Decorators make defining new properties or modifying existing ones easy:
class C(object):
    @property
    def x(self): return self._x
    @x.setter
    def x(self, value): self._x = value
    @x.deleter
    def x(self): del self._x

Callable : quit > None

Callable : range > range([start,] stop[, step]) -> list of integers

Return a list containing an arithmetic progression of integers.
range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
When step is given, it specifies the increment (or decrement).
For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!
These are exactly the valid indices for a list of 4 elements.

Callable : raw_input > raw_input([prompt]) -> string

Read a string from standard input.  The trailing newline is stripped.
If the user hits EOF (Unix: Ctl-D, Windows: Ctl-Z+Return), raise EOFError.
On Unix, GNU readline is used if enabled.  The prompt string, if given,
is printed without a trailing newline before reading.

Callable : reduce > reduce(function, sequence[, initial]) -> value

Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5).  If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.

Callable : reload > reload(module) -> module

Reload the module.  The module must have been successfully imported before.

Callable : repr > repr(object) -> string

Return the canonical string representation of the object.
For most object types, eval(repr(object)) == object.

Callable : reversed > reversed(sequence) -> reverse iterator over values of the sequence

Return a reverse iterator

Callable : round > round(number[, ndigits]) -> floating point number

Round a number to a given precision in decimal digits (default 0 digits).
This always returns a floating point number.  Precision may be negative.

Callable : set > set() -> new empty set object
set(iterable) -> new set object

Build an unordered collection of unique elements.

Callable : setattr > setattr(object, name, value)

Set a named attribute on an object; setattr(x, 'y', v) is equivalent to
``x.y = v''.

Callable : slice > slice([start,] stop[, step])

Create a slice object.  This is used for extended slicing (e.g. a[0:10:2]).

Callable : sorted > sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list

Callable : staticmethod > staticmethod(function) -> method

Convert a function to be a static method.

A static method does not receive an implicit first argument.
To declare a static method, use this idiom:

     class C:
     def f(arg1, arg2, ...): ...
     f = staticmethod(f)

It can be called either on the class (e.g. C.f()) or on an instance
(e.g. C().f()).  The instance is ignored except for its class.

Static methods in Python are similar to those found in Java or C++.
For a more advanced concept, see the classmethod builtin.

Callable : str > str(object) -> string

Return a nice string representation of the object.
If the argument is a string, the return value is the same object.

Callable : sum > sum(sequence[, start]) -> value

Returns the sum of a sequence of numbers (NOT strings) plus the value
of parameter 'start' (which defaults to 0).  When the sequence is
empty, returns start.

Callable : super > super(type) -> unbound super object
super(type, obj) -> bound super object; requires isinstance(obj, type)
super(type, type2) -> bound super object; requires issubclass(type2, type)
Typical use to call a cooperative superclass method:
class C(B):
    def meth(self, arg):
        super(C, self).meth(arg)

Callable : tuple > tuple() -> empty tuple
tuple(iterable) -> tuple initialized from iterable's items

If the argument is a tuple, the return value is the same object.

Callable : type > type(object) -> the object's type
type(name, bases, dict) -> a new type

Callable : unichr > unichr(i) -> Unicode character

Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff.

Callable : unicode > unicode(string [, encoding[, errors]]) -> object

Create a new Unicode object from the given encoded string.
encoding defaults to the current default string encoding.
errors can be 'strict', 'replace' or 'ignore' and defaults to 'strict'.

Callable : vars > vars([object]) -> dictionary

Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.

Callable : xrange > xrange([start,] stop[, step]) -> xrange object

Like range(), but instead of returning a list, returns an object that
generates the numbers in the range on demand.  For looping, this is 
slightly faster than range() and more memory efficient.

Callable : zip > zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]

Return a list of tuples, where each tuple contains the i-th element
from each of the argument sequences.  The returned list is truncated
in length to the length of the shortest argument sequence.