2

私は静的型プログラミングの出身であり、動的型プログラミングの背後にある理論的根拠を理解し、動的型言語が私のニーズにより適しているかどうかを確認することに興味があります。

ダックプログラミングの背後にある理論について読んだことがあります。また、コンパイル時のチェックが欠落している動的言語では、単体テスト (静的型プログラミングで望ましく使用される) が必要になることも読みました。

しかし、私はまだ全体像を見逃すことを恐れています。特に、変数の型が誤って変更された場合のミスをどのようにチェックできますか?

Python で非常に簡単な例を作成してみましょう。

#! /usr/bin/env python

userid = 3
defaultname = "foo"

username = raw_input("Enter your name: ")
if username == defaultname:
    # Bug: here we meant userid...
    username = 2

# Here username can be either an int or a string
# depending on the branch taken.
import re
match_string = re.compile("oo")
if (match_string.match(username)):
        print "Match!"

Pylint、pychecker、および pyflakes は、この問題について警告しません。

この種のエラーを処理するPythonicの方法は何ですか?

コードを try/catch でラップする必要がありますか?

4

1 に答える 1

0

これはコンパイル時にチェックを提供しませんが、try/catch の使用を提案したように、実行時チェックも役立つと思います。

クラスを使用する場合は、独自の型チェックを__setattr__メソッドにフックできます。例えば:

import datetime

# ------------------------------------------------------------------------------
# TypedObject
# ------------------------------------------------------------------------------
class TypedObject(object):     
    attr_types = {'id'         : int,
                  'start_time' : datetime.time,
                  'duration'   : float}

    __slots__ = attr_types.keys()

    # --------------------------------------------------------------------------
    # __setattr__
    # --------------------------------------------------------------------------
    def __setattr__(self, name, value):
        if name not in self.__slots__:
            raise AttributeError(
                "'%s' object has no attribute '%s'" 
                % (self.__class__.__name__, name))
        if type(value) is not self.attr_types[name]:
                raise TypeError(
                    "'%s' object attribute '%s' must be of type '%s'" 
                    % (self.__class__.__name__, name, 
                       self.attr_types[name].__name__))
        # call __setattr__ on parent class
        super(MyTypedObject, self).__setattr__(name, value)

その結果、次のようになります。

>>> my_typed_object            = TypedObject()

>>> my_typed_object.id         = "XYZ"      # ERROR
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 28, in __setattr__
TypeError: 'MyTypedObject' object attribute 'id' must be of type 'int'

>>> my_typed_object.id         = 123        # OK

続けて、TypedObject上記をより一般的なものにして、クラスがそれを継承できるようにすることができます。

別の (おそらくより良い) 解決策 (ここで指摘) は、 Entought Traitsを使用することです。

于 2013-06-11T12:04:39.917 に答える