Repository: joke2k/faker
Pull request #570 (2017-08-15 06:49:22)

Per generator seeding
This PR is intended to fix the issue in #349.

After let all the providers using the same generator, we should be able to have the following behavior:

```
>>> import faker
>>> # making sure seeding in separate faker instance will have the same results
...
>>> f1 = faker.Faker()
>>> f2 = faker.Faker()
>>> f1.seed(123)
>>> f1.address()
'4106 Peterson Center\nEast Matthew, LA 20619'
>>> f2.seed(123)
>>> f2.address()
'4106 Peterson Center\nEast Matthew, LA 20619'
>>> f1.address()
'7101 David Brooks\nRhondashire, MT 70458-7398'
>>> f2.address()
'7101 David Brooks\nRhondashire, MT 70458-7398'
>>>
>>> # seed module in f1 and should have the same outcome in fm1 and fm2 as they're using module level random obj
...
>>> fm1 = faker.Faker()
>>> fm2 = faker.Faker()
>>> f1.seed_module(456)
>>> fm1.address()
'6098 Mark Terrace Apt. 177\nWest Edwardborough, FL 89898-7519'
>>> f1.seed_module(456)
>>> fm2.address()
'6098 Mark Terrace Apt. 177\nWest Edwardborough, FL 89898-7519'
```

By default all the instance will still use the module level random object. Only when first time `instance.seed(int)` being called it will then create a new random object dedicate for the instance.


Patch:
diff --git a/Makefile b/Makefile
index 0caaa8cd..7f0f7b2b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 test:
-	coverage run --source=faker setup.py test
+	coverage run --source=faker --omit=faker/build_docs.py setup.py test
 
 release:
 	rm -rf build dist
diff --git a/faker/generator.py b/faker/generator.py
index 80c6a6c2..3f6cfa19 100644
--- a/faker/generator.py
+++ b/faker/generator.py
@@ -7,7 +7,7 @@ import random
 
 
 _re_token = re.compile(r'\{\{(\s?)(\w+)(\s?)\}\}')
-random = random.Random()
+mod_random = random.Random()
 
 
 class Generator(object):
@@ -18,6 +18,7 @@ class Generator(object):
         self.providers = []
         self.__config = dict(
             list(self.__config.items()) + list(config.items()))
+        self.__random = mod_random
 
     def add_provider(self, provider):
 
@@ -52,11 +53,18 @@ class Generator(object):
 
     @property
     def random(self):
-        return random
+        return self.__random
 
-    def seed(self, seed=None):
+    def seed_instance(self, seed=None):
         """Calls random.seed"""
-        random.seed(seed)
+        if self.__random == mod_random:
+            # create per-instance random obj when first time seed_instance() is called
+            self.__random = random.Random()
+        self.__random.seed(seed)
+
+    @classmethod
+    def seed(cls, seed=None):
+        mod_random.seed(seed)
 
     def format(self, formatter, *args, **kwargs):
         """
diff --git a/faker/providers/__init__.py b/faker/providers/__init__.py
index 7e2e5a18..b7511de2 100644
--- a/faker/providers/__init__.py
+++ b/faker/providers/__init__.py
@@ -3,7 +3,6 @@
 import re
 import string
 
-from faker.generator import random
 from faker.utils.distribution import choice_distribution
 
 
@@ -22,8 +21,7 @@ class BaseProvider(object):
     def __init__(self, generator):
         self.generator = generator
 
-    @classmethod
-    def random_int(cls, min=0, max=9999):
+    def random_int(self, min=0, max=9999):
         """
         Returns a random integer between two values.
 
@@ -31,48 +29,43 @@ class BaseProvider(object):
         :param max: upper bound value (inclusive; default=9999)
         :returns: random integer between min and max
         """
-        return random.randint(min, max)
+        return self.generator.random.randint(min, max)
 
-    @classmethod
-    def random_digit(cls):
+    def random_digit(self):
         """
         Returns a random digit/number
         between 0 and 9.
         """
-        return random.randint(0, 9)
+        return self.generator.random.randint(0, 9)
 
-    @classmethod
-    def random_digit_not_null(cls):
+    def random_digit_not_null(self):
         """
         Returns a random non-zero digit/number
         between 1 and 9.
         """
-        return random.randint(1, 9)
+        return self.generator.random.randint(1, 9)
 
-    @classmethod
-    def random_digit_or_empty(cls):
+    def random_digit_or_empty(self):
         """
         Returns a random digit/number
         between 0 and 9 or an empty string.
         """
-        if random.randint(0, 1):
-            return random.randint(0, 9)
+        if self.generator.random.randint(0, 1):
+            return self.generator.random.randint(0, 9)
         else:
             return ''
 
-    @classmethod
-    def random_digit_not_null_or_empty(cls):
+    def random_digit_not_null_or_empty(self):
         """
         Returns a random non-zero digit/number
         between 1 and 9 or and empty string.
         """
-        if random.randint(0, 1):
-            return random.randint(1, 9)
+        if self.generator.random.randint(0, 1):
+            return self.generator.random.randint(1, 9)
         else:
             return ''
 
-    @classmethod
-    def random_number(cls, digits=None, fix_len=False):
+    def random_number(self, digits=None, fix_len=False):
         """
         Returns a random number with 1 digit (default, when digits==None),
         a random number with 0 to given number of digits, or a random number
@@ -84,19 +77,17 @@ class BaseProvider(object):
             fixed length number
         """
         if digits is None:
-            digits = BaseProvider.random_digit()
+            digits = self.random_digit()
         if fix_len:
-            return random.randint(pow(10, digits - 1), pow(10, digits) - 1)
+            return self.generator.random.randint(pow(10, digits - 1), pow(10, digits) - 1)
         else:
-            return random.randint(0, pow(10, digits) - 1)
+            return self.generator.random.randint(0, pow(10, digits) - 1)
 
-    @classmethod
-    def random_letter(cls):
+    def random_letter(self):
         """Returns a random letter (between a-z and A-Z)."""
-        return random.choice(getattr(string, 'letters', string.ascii_letters))
+        return self.generator.random.choice(getattr(string, 'letters', string.ascii_letters))
 
-    @classmethod
-    def random_element(cls, elements=('a', 'b', 'c')):
+    def random_element(self, elements=('a', 'b', 'c')):
         """
         Returns a random element from a passed object.
 
@@ -116,34 +107,31 @@ class BaseProvider(object):
         if isinstance(elements, dict):
             choices = elements.keys()
             probabilities = elements.values()
-            return choice_distribution(list(choices), list(probabilities))
+            return choice_distribution(list(choices), list(probabilities), self.generator.random)
         else:
-            return random.choice(list(elements))
+            return self.generator.random.choice(list(elements))
 
-    @classmethod
-    def random_sample(cls, elements=('a', 'b', 'c'), length=None):
+    def random_sample(self, elements=('a', 'b', 'c'), length=None):
         if length is None:
-            length = random.randint(1, len(elements))
+            length = self.generator.random.randint(1, len(elements))
 
-        return [cls.random_element(elements) for _ in range(length)]
+        return [self.random_element(elements) for _ in range(length)]
 
-    @classmethod
-    def random_sample_unique(cls, elements=('a', 'b', 'c'), length=None):
+    def random_sample_unique(self, elements=('a', 'b', 'c'), length=None):
         """
         Returns a `set` of random unique elements for the specified length.
         """
         if length is None:
-            length = random.randint(1, len(elements))
+            length = self.generator.random.randint(1, len(elements))
 
         if length > len(elements):
             raise ValueError("Sample length cannot be longer than the number of elements to pick from.")
         sample = set()
         while len(sample) < length:
-            sample.add(cls.random_element(elements))
+            sample.add(self.random_element(elements))
         return sample
 
-    @classmethod
-    def randomize_nb_elements(cls, number=10, le=False, ge=False):
+    def randomize_nb_elements(self, number=10, le=False, ge=False):
         """
         Returns a random value near number.
 
@@ -156,10 +144,9 @@ class BaseProvider(object):
             return number
         _min = 100 if ge else 60
         _max = 100 if le else 140
-        return int(number * random.randint(_min, _max) / 100) + 1
+        return int(number * self.generator.random.randint(_min, _max) / 100)
 
-    @classmethod
-    def numerify(cls, text='###'):
+    def numerify(self, text='###'):
         """
         Replaces all placeholders in given text with randomized values,
         replacing: all hash sign ('#') occurrences with a random digit
@@ -173,35 +160,33 @@ class BaseProvider(object):
         :returns: string with all numerical placeholders filled in
         """
         text = _re_hash.sub(
-            lambda x: str(BaseProvider.random_digit()),
+            lambda x: str(self.random_digit()),
             text)
         text = _re_perc.sub(
-            lambda x: str(BaseProvider.random_digit_not_null()),
+            lambda x: str(self.random_digit_not_null()),
             text)
         text = _re_excl.sub(
-            lambda x: str(BaseProvider.random_digit_or_empty()),
+            lambda x: str(self.random_digit_or_empty()),
             text)
         text = _re_at.sub(
-            lambda x: str(BaseProvider.random_digit_not_null_or_empty()),
+            lambda x: str(self.random_digit_not_null_or_empty()),
             text)
         return text
 
-    @classmethod
-    def lexify(cls, text='????'):
+    def lexify(self, text='????'):
         """
         Replaces all question mark ('?') occurrences with a random letter.
 
         :param text: string to be parsed
         :returns: string with all letter placeholders filled in
         """
-        return _re_qm.sub(lambda x: BaseProvider.random_letter(), text)
+        return _re_qm.sub(lambda x: self.random_letter(), text)
 
-    @classmethod
-    def bothify(cls, text='## ??'):
+    def bothify(self, text='## ??'):
         """
         Replaces all placeholders with random numbers and letters.
 
         :param text: string to be parsed
         :returns: string with all numerical and letter placeholders filled in
         """
-        return BaseProvider.lexify(BaseProvider.numerify(text))
+        return self.lexify(self.numerify(text))
diff --git a/faker/providers/address/__init__.py b/faker/providers/address/__init__.py
index 9be123cc..ff39972b 100644
--- a/faker/providers/address/__init__.py
+++ b/faker/providers/address/__init__.py
@@ -4,7 +4,6 @@ from decimal import Decimal
 
 from .. import BaseProvider
 from .. import date_time
-from faker.generator import random
 
 localized = True
 
@@ -21,26 +20,23 @@ class Provider(BaseProvider):
     countries = [tz['name'] for tz in date_time.Provider.countries]
     country_codes = [tz['code'] for tz in date_time.Provider.countries]
 
-    @classmethod
-    def city_suffix(cls):
+    def city_suffix(self):
         """
         :example 'town'
         """
-        return cls.random_element(cls.city_suffixes)
+        return self.random_element(self.city_suffixes)
 
-    @classmethod
-    def street_suffix(cls):
+    def street_suffix(self):
         """
         :example 'Avenue'
         """
-        return cls.random_element(cls.street_suffixes)
+        return self.random_element(self.street_suffixes)
 
-    @classmethod
-    def building_number(cls):
+    def building_number(self):
         """
         :example '791'
         """
-        return cls.numerify(cls.random_element(cls.building_number_formats))
+        return self.numerify(self.random_element(self.building_number_formats))
 
     def city(self):
         """
@@ -63,12 +59,11 @@ class Provider(BaseProvider):
         pattern = self.random_element(self.street_address_formats)
         return self.generator.parse(pattern)
 
-    @classmethod
-    def postcode(cls):
+    def postcode(self):
         """
         :example 86039-9874
         """
-        return cls.bothify(cls.random_element(cls.postcode_formats)).upper()
+        return self.bothify(self.random_element(self.postcode_formats)).upper()
 
     def address(self):
         """
@@ -77,32 +72,27 @@ class Provider(BaseProvider):
         pattern = self.random_element(self.address_formats)
         return self.generator.parse(pattern)
 
-    @classmethod
-    def country(cls):
-        return cls.random_element(cls.countries)
+    def country(self):
+        return self.random_element(self.countries)
 
-    @classmethod
-    def country_code(cls):
-        return cls.random_element(cls.country_codes)
+    def country_code(self):
+        return self.random_element(self.country_codes)
 
-    @classmethod
-    def geo_coordinate(cls, center=None, radius=0.001):
+    def geo_coordinate(self, center=None, radius=0.001):
         """
         Optionally center the coord and pick a point within radius.
         """
         if center is None:
-            return Decimal(str(random.randint(-180000000, 180000000) / 1000000.0)).quantize(Decimal('.000001'))
+            return Decimal(str(self.generator.random.randint(-180000000, 180000000) / 1000000.0)).quantize(Decimal('.000001'))
         else:
             center = float(center)
             radius = float(radius)
-            geo = random.uniform(center - radius, center + radius)
+            geo = self.generator.random.uniform(center - radius, center + radius)
             return Decimal(str(geo)).quantize(Decimal('.000001'))
 
-    @classmethod
-    def latitude(cls):
+    def latitude(self):
         # Latitude has a range of -90 to 90, so divide by two.
-        return cls.geo_coordinate() / 2
+        return self.geo_coordinate() / 2
 
-    @classmethod
-    def longitude(cls):
-        return cls.geo_coordinate()
+    def longitude(self):
+        return self.geo_coordinate()
diff --git a/faker/providers/address/cs_CZ/__init__.py b/faker/providers/address/cs_CZ/__init__.py
index c812232d..29570a99 100644
--- a/faker/providers/address/cs_CZ/__init__.py
+++ b/faker/providers/address/cs_CZ/__init__.py
@@ -742,22 +742,17 @@ class Provider(AddressProvider):
         'Švédsko',
         'Švýcarsko')
 
-    @classmethod
-    def street_suffix_short(cls):
-        return cls.random_element(cls.street_suffixes_short)
+    def street_suffix_short(self):
+        return self.random_element(self.street_suffixes_short)
 
-    @classmethod
-    def street_suffix_long(cls):
-        return cls.random_element(cls.street_suffixes_long)
+    def street_suffix_long(self):
+        return self.random_element(self.street_suffixes_long)
 
-    @classmethod
-    def city_name(cls):
-        return cls.random_element(cls.cities)
+    def city_name(self):
+        return self.random_element(self.cities)
 
-    @classmethod
-    def street_name(cls):
-        return cls.random_element(cls.streets)
+    def street_name(self):
+        return self.random_element(self.streets)
 
-    @classmethod
-    def state(cls):
-        return cls.random_element(cls.states)
+    def state(self):
+        return self.random_element(self.states)
diff --git a/faker/providers/address/de_DE/__init__.py b/faker/providers/address/de_DE/__init__.py
index 8e212871..707dd866 100644
--- a/faker/providers/address/de_DE/__init__.py
+++ b/faker/providers/address/de_DE/__init__.py
@@ -174,22 +174,17 @@ class Provider(AddressProvider):
         'Äquatorialguinea', 'Äthiopien', 'Äußeres Ozeanien', 'Österreich',
     )
 
-    @classmethod
-    def street_suffix_short(cls):
-        return cls.random_element(cls.street_suffixes_short)
+    def street_suffix_short(self):
+        return self.random_element(self.street_suffixes_short)
 
-    @classmethod
-    def street_suffix_long(cls):
-        return cls.random_element(cls.street_suffixes_long)
+    def street_suffix_long(self):
+        return self.random_element(self.street_suffixes_long)
 
-    @classmethod
-    def city_name(cls):
-        return cls.random_element(cls.cities)
+    def city_name(self):
+        return self.random_element(self.cities)
 
-    @classmethod
-    def state(cls):
-        return cls.random_element(cls.states)
+    def state(self):
+        return self.random_element(self.states)
 
-    @classmethod
-    def country(cls):
-        return cls.random_element(cls.countries)
\ No newline at end of file
+    def country(self):
+        return self.random_element(self.countries)
diff --git a/faker/providers/address/el_GR/__init__.py b/faker/providers/address/el_GR/__init__.py
index 1afc29fd..284d8bff 100644
--- a/faker/providers/address/el_GR/__init__.py
+++ b/faker/providers/address/el_GR/__init__.py
@@ -3,7 +3,6 @@ from __future__ import unicode_literals
 from decimal import Decimal
 
 from .. import Provider as AddressProvider
-from faker.generator import random
 
 
 def contains_point(poly, point):
@@ -89,43 +88,34 @@ class Provider(AddressProvider):
         pattern = self.random_element(self.line_address_formats)
         return self.generator.parse(pattern)
 
-    @classmethod
-    def street_prefix(cls):
-        return cls.random_element(cls.street_prefixes_short + cls.street_prefixes_long)
+    def street_prefix(self):
+        return self.random_element(self.street_prefixes_short + self.street_prefixes_long)
 
-    @classmethod
-    def street_prefix_short(cls):
-        return cls.random_element(cls.street_prefixes_short)
+    def street_prefix_short(self):
+        return self.random_element(self.street_prefixes_short)
 
-    @classmethod
-    def street_prefix_long(cls):
-        return cls.random_element(cls.street_prefixes_long)
+    def street_prefix_long(self):
+        return self.random_element(self.street_prefixes_long)
 
-    @classmethod
-    def street(cls):
-        return cls.random_element(cls.localities)
+    def street(self):
+        return self.random_element(self.localities)
 
-    @classmethod
-    def city(cls):
-        return cls.random_element(cls.cities)
+    def city(self):
+        return self.random_element(self.cities)
 
-    @classmethod
-    def region(cls):
-        return cls.random_element(cls.regions)
+    def region(self):
+        return self.random_element(self.regions)
 
-    @classmethod
-    def latlng(cls):
-        return float(cls.latitude()), float(cls.longitude())
-    
-    @classmethod
-    def latitude(cls):
-        l = list(map(lambda t: int(t[0] * 10000000), cls.poly))
-        return Decimal(str(random.randint(min(l), max(l)) / 10000000.0)).quantize(Decimal('.000001'))
+    def latlng(self):
+        return float(self.latitude()), float(self.longitude())
 
-    @classmethod
-    def longitude(cls):
-        l = list(map(lambda t: int(t[1] * 10000000), cls.poly))
-        return Decimal(str(random.randint(min(l), max(l)) / 10000000.0)).quantize(Decimal('.000001'))
+    def latitude(self):
+        l = list(map(lambda t: int(t[0] * 10000000), self.poly))
+        return Decimal(str(self.generator.random.randint(min(l), max(l)) / 10000000.0)).quantize(Decimal('.000001'))
+
+    def longitude(self):
+        l = list(map(lambda t: int(t[1] * 10000000), self.poly))
+        return Decimal(str(self.generator.random.randint(min(l), max(l)) / 10000000.0)).quantize(Decimal('.000001'))
 
     # Ονόματα πρωτευουσών νομών
     cities = (
diff --git a/faker/providers/address/en_AU/__init__.py b/faker/providers/address/en_AU/__init__.py
index 35a981a6..ac2e2f1e 100644
--- a/faker/providers/address/en_AU/__init__.py
+++ b/faker/providers/address/en_AU/__init__.py
@@ -123,18 +123,14 @@ class Provider(AddressProvider):
     secondary_address_formats = ('Apt. ###', 'Flat ##', 'Suite ###', 'Unit ##',
                                  'Level #', '### /', '## /', '# /')
 
-    @classmethod
-    def city_prefix(cls):
-        return cls.random_element(cls.city_prefixes)
+    def city_prefix(self):
+        return self.random_element(self.city_prefixes)
 
-    @classmethod
-    def secondary_address(cls):
-        return cls.numerify(cls.random_element(cls.secondary_address_formats))
+    def secondary_address(self):
+        return self.numerify(self.random_element(self.secondary_address_formats))
 
-    @classmethod
-    def state(cls):
-        return cls.random_element(cls.states)
+    def state(self):
+        return self.random_element(self.states)
 
-    @classmethod
-    def state_abbr(cls):
-        return cls.random_element(cls.states_abbr)
+    def state_abbr(self):
+        return self.random_element(self.states_abbr)
diff --git a/faker/providers/address/en_CA/__init__.py b/faker/providers/address/en_CA/__init__.py
index 21f40b90..a5d180a5 100644
--- a/faker/providers/address/en_CA/__init__.py
+++ b/faker/providers/address/en_CA/__init__.py
@@ -81,41 +81,34 @@ class Provider(AddressProvider):
     )
     secondary_address_formats = ('Apt. ###', 'Suite ###')
 
-    @classmethod
-    def province(cls):
+    def province(self):
         """
         """
-        return cls.random_element(cls.provinces)
+        return self.random_element(self.provinces)
 
-    @classmethod
-    def province_abbr(cls):
-        return cls.random_element(cls.provinces_abbr)
+    def province_abbr(self):
+        return self.random_element(self.provinces_abbr)
 
-    @classmethod
-    def city_prefix(cls):
-        return cls.random_element(cls.city_prefixes)
+    def city_prefix(self):
+        return self.random_element(self.city_prefixes)
 
-    @classmethod
-    def secondary_address(cls):
-        return cls.numerify(cls.random_element(cls.secondary_address_formats))
+    def secondary_address(self):
+        return self.numerify(self.random_element(self.secondary_address_formats))
 
-    @classmethod
-    def postal_code_letter(cls):
+    def postal_code_letter(self):
         """
         Returns a random letter from the list of allowable
         letters in a canadian postal code
         """
-        return cls.random_element(cls.postal_code_letters)
+        return self.random_element(self.postal_code_letters)
 
-    @classmethod
-    def postalcode(cls):
+    def postalcode(self):
         """
         Replaces all question mark ('?') occurrences with a random letter
         from postal_code_formats then passes result to
         numerify to insert numbers
         """
         temp = re.sub(r'\?',
-            lambda x: cls.postal_code_letter(),
-            cls.random_element(cls.postal_code_formats))
-        return cls.numerify(temp)
-
+            lambda x: self.postal_code_letter(),
+            self.random_element(self.postal_code_formats))
+        return self.numerify(temp)
diff --git a/faker/providers/address/en_GB/__init__.py b/faker/providers/address/en_GB/__init__.py
index bf05b4da..3e81e139 100644
--- a/faker/providers/address/en_GB/__init__.py
+++ b/faker/providers/address/en_GB/__init__.py
@@ -101,21 +101,18 @@ class Provider(AddressProvider):
     )
     secondary_address_formats = ('Flat #', 'Flat ##', 'Flat ##?', 'Studio #', 'Studio ##', 'Studio ##?')
 
-    @classmethod
-    def postcode(cls):
+    def postcode(self):
         """
         See http://web.archive.org/web/20090930140939/http://www.govtalk.gov.uk/gdsc/html/noframes/PostCode-2-1-Release.htm
         """
         postcode = ''
-        pattern = cls.random_element(cls.postcode_formats)
+        pattern = self.random_element(self.postcode_formats)
         for placeholder in pattern:
-            postcode += cls.random_element(cls._postcode_sets[placeholder])
+            postcode += self.random_element(self._postcode_sets[placeholder])
         return postcode
 
-    @classmethod
-    def city_prefix(cls):
-        return cls.random_element(cls.city_prefixes)
+    def city_prefix(self):
+        return self.random_element(self.city_prefixes)
 
-    @classmethod
-    def secondary_address(cls):
-        return cls.bothify(cls.random_element(cls.secondary_address_formats))
+    def secondary_address(self):
+        return self.bothify(self.random_element(self.secondary_address_formats))
diff --git a/faker/providers/address/en_US/__init__.py b/faker/providers/address/en_US/__init__.py
index 345faa3c..8520ccf5 100644
--- a/faker/providers/address/en_US/__init__.py
+++ b/faker/providers/address/en_US/__init__.py
@@ -2,7 +2,6 @@ from __future__ import unicode_literals
 from collections import OrderedDict
 
 from ..en import Provider as AddressProvider
-from faker.generator import random
 
 
 class Provider(AddressProvider):
@@ -107,63 +106,51 @@ class Provider(AddressProvider):
 
     secondary_address_formats = ('Apt. ###', 'Suite ###')
 
-    @classmethod
-    def city_prefix(cls):
-        return cls.random_element(cls.city_prefixes)
+    def city_prefix(self):
+        return self.random_element(self.city_prefixes)
 
-    @classmethod
-    def secondary_address(cls):
-        return cls.numerify(cls.random_element(cls.secondary_address_formats))
+    def secondary_address(self):
+        return self.numerify(self.random_element(self.secondary_address_formats))
 
-    @classmethod
-    def state(cls):
-        return cls.random_element(cls.states)
+    def state(self):
+        return self.random_element(self.states)
 
-    @classmethod
-    def state_abbr(cls):
-        return cls.random_element(cls.states_abbr)
+    def state_abbr(self):
+        return self.random_element(self.states_abbr)
 
-    @classmethod
-    def zipcode(cls):
-        return "%05d" % random.randint(501, 99950)
+    def zipcode(self):
+        return "%05d" % self.generator.random.randint(501, 99950)
 
-    @classmethod
-    def zipcode_plus4(cls):
-        return "%s-%04d" % (cls.zipcode(), random.randint(1, 9999))
+    def zipcode_plus4(self):
+        return "%s-%04d" % (self.zipcode(), self.generator.random.randint(1, 9999))
 
-    @classmethod
-    def military_ship(cls):
+    def military_ship(self):
         """
         :example 'USS'
         """
-        return cls.random_element(cls.military_ship_prefix)
+        return self.random_element(self.military_ship_prefix)
 
-    @classmethod
-    def military_state(cls):
+    def military_state(self):
         """
         :example 'APO'
         """
-        return cls.random_element(cls.military_state_abbr)
+        return self.random_element(self.military_state_abbr)
 
-    @classmethod
-    def military_apo(cls):
+    def military_apo(self):
         """
         :example 'PSC 5394 Box 3492
         """
-        return cls.numerify(cls.military_apo_format)
+        return self.numerify(self.military_apo_format)
 
-    @classmethod
-    def military_dpo(cls):
+    def military_dpo(self):
         """
         :example 'Unit 3333 Box 9342'
         """
-        return cls.numerify(cls.military_dpo_format)
+        return self.numerify(self.military_dpo_format)
 
     # Aliases
-    @classmethod
-    def postalcode(cls):
-        return cls.zipcode()
+    def postalcode(self):
+        return self.zipcode()
 
-    @classmethod
-    def postalcode_plus4(cls):
-        return cls.zipcode_plus4()
+    def postalcode_plus4(self):
+        return self.zipcode_plus4()
diff --git a/faker/providers/address/es_ES/__init__.py b/faker/providers/address/es_ES/__init__.py
index 132bbabc..316bc1a6 100644
--- a/faker/providers/address/es_ES/__init__.py
+++ b/faker/providers/address/es_ES/__init__.py
@@ -41,18 +41,14 @@ class Provider(AddressProvider):
     )
     secondary_address_formats = ('Apt. ##', 'Piso #', 'Puerta #')
 
-    @classmethod
-    def state_name(cls):
-        return cls.random_element(cls.states)
+    def state_name(self):
+        return self.random_element(self.states)
 
-    @classmethod
-    def street_prefix(cls):
-        return cls.random_element(cls.street_prefixes)
+    def street_prefix(self):
+        return self.random_element(self.street_prefixes)
 
-    @classmethod
-    def secondary_address(cls):
-        return cls.numerify(cls.random_element(cls.secondary_address_formats))
+    def secondary_address(self):
+        return self.numerify(self.random_element(self.secondary_address_formats))
 
-    @classmethod
-    def state(cls):
-        return cls.random_element(cls.states)
+    def state(self):
+        return self.random_element(self.states)
diff --git a/faker/providers/address/es_MX/__init__.py b/faker/providers/address/es_MX/__init__.py
index f58ad4de..7fdd436b 100644
--- a/faker/providers/address/es_MX/__init__.py
+++ b/faker/providers/address/es_MX/__init__.py
@@ -93,42 +93,35 @@ class Provider(AddressProvider):
     secondary_address_formats = ('### ###', '### Interior ###',
         '### Edif. ### , Depto. ###')
 
-    @classmethod
-    def city_prefix(cls):
-        return cls.random_element(cls.city_prefixes)
+    def city_prefix(self):
+        return self.random_element(self.city_prefixes)
 
-    @classmethod
-    def city_suffix(cls):
-        return cls.random_element(cls.city_suffixies)
+    def city_suffix(self):
+        return self.random_element(self.city_suffixies)
 
-    @classmethod
-    def city_adjetive(cls):
-        return cls.random_element(cls.city_adjetives)
+    def city_adjetive(self):
+        return self.random_element(self.city_adjetives)
 
-    @classmethod
-    def street_prefix(cls):
+    def street_prefix(self):
         """
         :example 'Avenida'
         """
-        return cls.random_element(cls.street_prefixes)
+        return self.random_element(self.street_prefixes)
 
-    @classmethod
-    def secondary_address(cls):
+    def secondary_address(self):
         """
         :example '020 Interior 999'
         """
-        return cls.numerify(cls.random_element(cls.secondary_address_formats))
+        return self.numerify(self.random_element(self.secondary_address_formats))
 
-    @classmethod
-    def state(cls):
+    def state(self):
         """
         example: u'Guerrero'
         """
-        return cls.random_element(cls.states)[1]
+        return self.random_element(self.states)[1]
 
-    @classmethod
-    def state_abbr(cls):
+    def state_abbr(self):
         """
         example: u'GRO'
         """
-        return cls.random_element(cls.states)[0]
+        return self.random_element(self.states)[0]
diff --git a/faker/providers/address/fa_IR/__init__.py b/faker/providers/address/fa_IR/__init__.py
index b0af12d4..0f37b92d 100644
--- a/faker/providers/address/fa_IR/__init__.py
+++ b/faker/providers/address/fa_IR/__init__.py
@@ -77,14 +77,11 @@ class Provider(AddressProvider):
     )
     secondary_address_formats = ('سوئیت ###', 'واحد ###')
 
-    @classmethod
-    def city_prefix(cls):
-        return cls.random_element(cls.city_prefixes)
+    def city_prefix(self):
+        return self.random_element(self.city_prefixes)
 
-    @classmethod
-    def secondary_address(cls):
-        return cls.numerify(cls.random_element(cls.secondary_address_formats))
+    def secondary_address(self):
+        return self.numerify(self.random_element(self.secondary_address_formats))
 
-    @classmethod
-    def state(cls):
-        return cls.random_element(cls.states)
+    def state(self):
+        return self.random_element(self.states)
diff --git a/faker/providers/address/fi_FI/__init__.py b/faker/providers/address/fi_FI/__init__.py
index b8aa22d5..cd8a9e6f 100644
--- a/faker/providers/address/fi_FI/__init__.py
+++ b/faker/providers/address/fi_FI/__init__.py
@@ -135,14 +135,11 @@ class Provider(AddressProvider):
         'Verkkomeloni', 'Vesimeloni', 'Viikuna', 'Viinirypäle'
     )
 
-    @classmethod
-    def fruit(cls):
-        return cls.random_element(cls.fruits)
+    def fruit(self):
+        return self.random_element(self.fruits)
 
-    @classmethod
-    def city_name(cls):
-        return cls.random_element(cls.cities)
+    def city_name(self):
+        return self.random_element(self.cities)
 
-    @classmethod
-    def state(cls):
-        return cls.random_element(cls.states)
+    def state(self):
+        return self.random_element(self.states)
diff --git a/faker/providers/address/fr_CH/__init__.py b/faker/providers/address/fr_CH/__init__.py
index 4b85ed6f..f585dc39 100644
--- a/faker/providers/address/fr_CH/__init__.py
+++ b/faker/providers/address/fr_CH/__init__.py
@@ -106,40 +106,35 @@ class Provider(AddressProvider):
         'Vierges britanniques (Îles)', 'Vietnam', 'Wallis et Futuna (Îles)',
         'Yemen', 'Yougoslavie', 'Zambie', 'Zaïre', 'Zimbabwe',)
 
-    @classmethod
-    def street_prefix(cls):
+    def street_prefix(self):
         """
         :example 'rue'
         """
-        return cls.random_element(cls.street_prefixes)
+        return self.random_element(self.street_prefixes)
 
-    @classmethod
-    def city_prefix(cls):
+    def city_prefix(self):
         """
         :example 'rue'
         """
-        return cls.random_element(cls.city_prefixes)
+        return self.random_element(self.city_prefixes)
 
-    @classmethod
-    def canton(cls):
+    def canton(self):
         """
         Randomly returns a swiss canton ('Abbreviated' , 'Name').
         :example ('VD' . 'Vaud')
         """
-        return cls.random_element(cls.cantons)
+        return self.random_element(self.cantons)
 
-    @classmethod
-    def canton_name(cls):
+    def canton_name(self):
         """
         Randomly returns a Swiss canton name.
         :example 'Vaud'
         """
-        return cls.canton()[1]
+        return self.canton()[1]
 
-    @classmethod
-    def canton_code(cls):
+    def canton_code(self):
         """
         Randomly returns a Swiss canton code.
         :example 'VD'
         """
-        return cls.canton()[0]
+        return self.canton()[0]
diff --git a/faker/providers/address/fr_FR/__init__.py b/faker/providers/address/fr_FR/__init__.py
index 1bfcc3dc..353d4c7b 100644
--- a/faker/providers/address/fr_FR/__init__.py
+++ b/faker/providers/address/fr_FR/__init__.py
@@ -110,48 +110,42 @@ class Provider(AddressProvider):
         ('971', 'Guadeloupe'), ('972', 'Martinique'), ('973', 'Guyane'), ('974', 'La Réunion'), ('976', 'Mayotte')
     )
 
-    @classmethod
-    def street_prefix(cls):
+    def street_prefix(self):
         """
         :example 'rue'
         """
-        return cls.random_element(cls.street_prefixes)
+        return self.random_element(self.street_prefixes)
 
-    @classmethod
-    def city_prefix(cls):
+    def city_prefix(self):
         """
         :example 'rue'
         """
-        return cls.random_element(cls.city_prefixes)
+        return self.random_element(self.city_prefixes)
 
-    @classmethod
-    def region(cls):
+    def region(self):
         """
         :example 'Guadeloupe'
         """
-        return cls.random_element(cls.regions)
+        return self.random_element(self.regions)
 
-    @classmethod
-    def department(cls):
+    def department(self):
         """
         Randomly returns a french department ('departmentNumber' , 'departmentName').
         :example ('2B' . 'Haute-Corse')
         """
-        return cls.random_element(cls.departments)
+        return self.random_element(self.departments)
 
-    @classmethod
-    def department_name(cls):
+    def department_name(self):
         """
         Randomly returns a french department name.
         :example 'Ardèche'
         """
-        return cls.department()[1]
+        return self.department()[1]
 
-    @classmethod
-    def department_number(cls):
+    def department_number(self):
         """
         Randomly returns a french department number.
 
         :example '59'
         """
-        return cls.department()[0]
+        return self.department()[0]
diff --git a/faker/providers/address/hi_IN/__init__.py b/faker/providers/address/hi_IN/__init__.py
index d23eca64..a7f57714 100644
--- a/faker/providers/address/hi_IN/__init__.py
+++ b/faker/providers/address/hi_IN/__init__.py
@@ -46,10 +46,8 @@ class Provider(AddressProvider):
         'उज़बेकिस्तान', 'यूनाइटेड किंगडम', 'वानुआतू', 'वेटिकन सिटी', 'वेनेजुएला', 'पश्चिमी सहारा', 'वियतनाम', 'यमन', 'ज़ायर', 'जाबम्बया', 'जिम्बाब्वे',
     )
 
-    @classmethod
-    def city_name(cls):
-        return cls.random_element(cls.cities)
+    def city_name(self):
+        return self.random_element(self.cities)
 
-    @classmethod
-    def state(cls):
-        return cls.random_element(cls.states)
+    def state(self):
+        return self.random_element(self.states)
diff --git a/faker/providers/address/hr_HR/__init__.py b/faker/providers/address/hr_HR/__init__.py
index df22506d..e8559e2d 100755
--- a/faker/providers/address/hr_HR/__init__.py
+++ b/faker/providers/address/hr_HR/__init__.py
@@ -166,14 +166,11 @@ class Provider(AddressProvider):
         "Wallis i Futuna", "Zambija", "Zapadna Sahara", "Zeleni Rt",
     )
 
-    @classmethod
-    def city_name(cls):
-        return cls.random_element(cls.cities)
+    def city_name(self):
+        return self.random_element(self.cities)
 
-    @classmethod
-    def street_name(cls):
-        return cls.random_element(cls.streets)
+    def street_name(self):
+        return self.random_element(self.streets)
 
-    @classmethod
-    def state(cls):
-        return cls.random_element(cls.states)
+    def state(self):
+        return self.random_element(self.states)
diff --git a/faker/providers/address/hu_HU/__init__.py b/faker/providers/address/hu_HU/__init__.py
index 0322a93f..e9e82b9a 100644
--- a/faker/providers/address/hu_HU/__init__.py
+++ b/faker/providers/address/hu_HU/__init__.py
@@ -102,47 +102,33 @@ class Provider(AddressProvider):
         "Uruguay", "Üzbegisztán", "Vanuatu", "Venezuela", "Vietnam", "Wallis és Futuna", "Zambia", "Zimbabwe",
         "Zöld-foki szigetek",)
 
-    @classmethod
-    def county(cls):
-        return cls.random_element(cls.counties)
+    def county(self):
+        return self.random_element(self.counties)
 
     def street_address_with_county(self):
         pattern = self.random_element(self.street_address_with_county_formats)
         return self.generator.parse(pattern)
 
-    @classmethod
-    def city_prefix(cls):
-        return cls.random_element(cls.city_prefs)
+    def city_prefix(self):
+        return self.random_element(self.city_prefs)
 
-    @classmethod
-    def city_part(cls):
-        return cls.random_element(cls.city_parts)
+    def city_part(self):
+        return self.random_element(self.city_parts)
 
-    @classmethod
-    def county(cls):
-        return cls.random_element(cls.counties)
+    def real_city_name(self):
+        return self.random_element(self.real_city_names)
 
-    @classmethod
-    def real_city_name(cls):
-        return cls.random_element(cls.real_city_names)
+    def frequent_street_name(self):
+        return self.random_element(self.frequent_street_names)
 
-    @classmethod
-    def frequent_street_name(cls):
-        return cls.random_element(cls.frequent_street_names)
-
-    def city(self):
-        return super(Provider, self).city()
-
-    @classmethod
-    def postcode(cls):
-        return "H-{}{}{}{}".format(super(Provider, cls).random_digit_not_null(), super(Provider, cls).random_digit(),
-                                   super(Provider, cls).random_digit(),
-                                   super(Provider, cls).random_digit())
+    def postcode(self):
+        return "H-{}{}{}{}".format(super(Provider, self).random_digit_not_null(), super(Provider, self).random_digit(),
+                                   super(Provider, self).random_digit(),
+                                   super(Provider, self).random_digit())
 
     def street_name(self):
         return super(Provider, self).street_name().title()
 
-    @classmethod
-    def building_number(cls):
-        numeric_part = super(Provider, cls).random_int(1, 250)
+    def building_number(self):
+        numeric_part = super(Provider, self).random_int(1, 250)
         return str(numeric_part) + "."
diff --git a/faker/providers/address/it_IT/__init__.py b/faker/providers/address/it_IT/__init__.py
index de97b65c..ec86f01b 100644
--- a/faker/providers/address/it_IT/__init__.py
+++ b/faker/providers/address/it_IT/__init__.py
@@ -107,18 +107,14 @@ class Provider(AddressProvider):
     )
     secondary_address_formats = ('Appartamento ##', 'Piano #')
 
-    @classmethod
-    def city_prefix(cls):
-        return cls.random_element(cls.city_prefixes)
+    def city_prefix(self):
+        return self.random_element(self.city_prefixes)
 
-    @classmethod
-    def secondary_address(cls):
-        return cls.numerify(cls.random_element(cls.secondary_address_formats))
+    def secondary_address(self):
+        return self.numerify(self.random_element(self.secondary_address_formats))
 
-    @classmethod
-    def state(cls):
-        return cls.random_element(cls.states)
+    def state(self):
+        return self.random_element(self.states)
 
-    @classmethod
-    def state_abbr(cls):
-        return cls.random_element(cls.states_abbr)
+    def state_abbr(self):
+        return self.random_element(self.states_abbr)
diff --git a/faker/providers/address/ja_JP/__init__.py b/faker/providers/address/ja_JP/__init__.py
index e850e930..fb1c65de 100644
--- a/faker/providers/address/ja_JP/__init__.py
+++ b/faker/providers/address/ja_JP/__init__.py
@@ -2,7 +2,6 @@
 from __future__ import unicode_literals
 
 from .. import Provider as AddressProvider
-from faker.generator import random
 
 
 class Provider(AddressProvider):
@@ -85,58 +84,50 @@ class Provider(AddressProvider):
         'パレス', 'ハイツ', 'コーポ', 'アーバン', 'クレスト', 'パーク', 'シティ', 'シャルム', 'コート',
     )
 
-    @classmethod
-    def prefecture(cls):
+    def prefecture(self):
         """
         :example '東京都'
         """
-        return cls.random_element(cls.prefectures)
+        return self.random_element(self.prefectures)
 
-    @classmethod
-    def city(cls):
+    def city(self):
         """
         :example '台東区'
         """
-        return cls.random_element(cls.cities)
+        return self.random_element(self.cities)
 
-    @classmethod
-    def town(cls):
+    def town(self):
         """
         :example '浅草'
         """
-        return cls.random_element(cls.towns)
+        return self.random_element(self.towns)
 
-    @classmethod
-    def chome(cls):
+    def chome(self):
         """
         :example '1丁目'
         """
-        return "%d丁目" % random.randint(1, 42)
+        return "%d丁目" % self.generator.random.randint(1, 42)
 
-    @classmethod
-    def ban(cls):
+    def ban(self):
         """
         :example '3番'
         """
-        return "%d番" % random.randint(1, 27)
+        return "%d番" % self.generator.random.randint(1, 27)
 
-    @classmethod
-    def gou(cls):
+    def gou(self):
         """
         :example '10号'
         """
-        return "%d号" % random.randint(1, 20)
+        return "%d号" % self.generator.random.randint(1, 20)
 
-    @classmethod
-    def building_name(cls):
+    def building_name(self):
         """
         :example 'コーポ芝浦'
         """
-        return cls.random_element(cls.building_names)
+        return self.random_element(self.building_names)
 
-    @classmethod
-    def zipcode(cls):
+    def zipcode(self):
         """
         :example '101-1212'
         """
-        return "%03d-%04d" % (random.randint(0, 999), random.randint(0, 9999))
+        return "%03d-%04d" % (self.generator.random.randint(0, 999), self.generator.random.randint(0, 9999))
diff --git a/faker/providers/address/ka_GE/__init__.py b/faker/providers/address/ka_GE/__init__.py
index 58d16f52..203968aa 100644
--- a/faker/providers/address/ka_GE/__init__.py
+++ b/faker/providers/address/ka_GE/__init__.py
@@ -300,10 +300,8 @@ class Provider(AddressProvider):
         'ჯვარი',
     )
 
-    @classmethod
-    def street_title(cls):
-        return cls.random_element(cls.street_titles)
+    def street_title(self):
+        return self.random_element(self.street_titles)
 
-    @classmethod
-    def city_name(cls):
-        return cls.random_element(cls.city_names)
+    def city_name(self):
+        return self.random_element(self.city_names)
diff --git a/faker/providers/address/ko_KR/__init__.py b/faker/providers/address/ko_KR/__init__.py
index 3713060e..952572e8 100644
--- a/faker/providers/address/ko_KR/__init__.py
+++ b/faker/providers/address/ko_KR/__init__.py
@@ -265,12 +265,11 @@ class Provider(AddressProvider):
     street_address_formats = road_address_formats
     address_formats = road_address_formats
 
-    @classmethod
-    def land_number(cls):
+    def land_number(self):
         """
         :example 507
         """
-        return cls.bothify(cls.random_element(cls.land_numbers))
+        return self.bothify(self.random_element(self.land_numbers))
 
     def land_address(self):
         """
@@ -279,12 +278,11 @@ class Provider(AddressProvider):
         pattern = self.random_element(self.land_address_formats)
         return self.generator.parse(pattern)
 
-    @classmethod
-    def road_number(cls):
+    def road_number(self):
         """
         :example 24
         """
-        return cls.bothify(cls.random_element(cls.road_numbers))
+        return self.bothify(self.random_element(self.road_numbers))
 
     def road_address(self):
         """
@@ -308,33 +306,29 @@ class Provider(AddressProvider):
         pattern = self.random_element(self.road_formats)
         return self.generator.parse(pattern)
 
-    @classmethod
-    def road_name(cls):
+    def road_name(self):
         """
         :example 압구정
         """
-        return cls.random_element(cls.road_names)
+        return self.random_element(self.road_names)
 
-    @classmethod
-    def road_suffix(cls):
+    def road_suffix(self):
         """
         :example 길
         """
-        return cls.random_element(cls.road_suffixes)
+        return self.random_element(self.road_suffixes)
 
-    @classmethod
-    def metropolitan_city(cls):
+    def metropolitan_city(self):
         """
         :example 서울특별시
         """
-        return cls.random_element(cls.metropolitan_cities)
+        return self.random_element(self.metropolitan_cities)
 
-    @classmethod
-    def province(cls):
+    def province(self):
         """
         :example 경기도
         """
-        return cls.random_element(cls.provinces)
+        return self.random_element(self.provinces)
 
     def city(self):
         """
@@ -343,12 +337,11 @@ class Provider(AddressProvider):
         pattern = self.random_element(self.cities)
         return self.generator.parse(pattern)
 
-    @classmethod
-    def borough(cls):
+    def borough(self):
         """
         :example 중구
         """
-        return cls.random_element(cls.boroughs)
+        return self.random_element(self.boroughs)
 
     def town(self):
         """
@@ -357,12 +350,11 @@ class Provider(AddressProvider):
         pattern = self.random_element(self.town_formats)
         return self.generator.parse(pattern)
 
-    @classmethod
-    def town_suffix(cls):
+    def town_suffix(self):
         """
         :example 동
         """
-        return cls.random_element(cls.town_suffixes)
+        return self.random_element(self.town_suffixes)
 
     def building_name(self):
         """
@@ -371,30 +363,26 @@ class Provider(AddressProvider):
         pattern = self.random_element(self.building_name_formats)
         return self.generator.parse(pattern)
 
-    @classmethod
-    def building_suffix(cls):
+    def building_suffix(self):
         """
         :example 아파트
         """
-        return cls.random_element(cls.building_suffixes)
+        return self.random_element(self.building_suffixes)
 
-    @classmethod
-    def building_dong(cls):
+    def building_dong(self):
         """
         :example 가
         """
-        return cls.bothify(cls.random_element(cls.building_dongs))
+        return self.bothify(self.random_element(self.building_dongs))
 
-    @classmethod
-    def old_postal_code(cls):
+    def old_postal_code(self):
         """
         :example 123-456
         """
-        return cls.bothify(cls.random_element(cls.postcode_formats))
+        return self.bothify(self.random_element(self.postcode_formats))
 
-    @classmethod
-    def postal_code(cls):
+    def postal_code(self):
         """
         :example 12345
         """
-        return cls.bothify(cls.random_element(cls.new_postal_code_formats))
+        return self.bothify(self.random_element(self.new_postal_code_formats))
diff --git a/faker/providers/address/ne_NP/__init__.py b/faker/providers/address/ne_NP/__init__.py
index 353ef015..38d1a7bc 100644
--- a/faker/providers/address/ne_NP/__init__.py
+++ b/faker/providers/address/ne_NP/__init__.py
@@ -80,23 +80,20 @@ class Provider(AddressProvider):
         'सिराहा', 'सुनसरी', 'सुर्खेत', 'सोलुखुम्बु', 'स्याङ्जा', 'हुम्ला',
     )
 
-    @classmethod
-    def district(cls):
+    def district(self):
         """
         :example अछाम
         """
-        return cls.random_element(cls.districts)
+        return self.random_element(self.districts)
 
-    @classmethod
-    def city(cls):
+    def city(self):
         """
         :example कावासोत
         """
-        return cls.random_element(cls.cities)
+        return self.random_element(self.cities)
 
-    @classmethod
-    def building_prefix(cls):
+    def building_prefix(self):
         """
         :example वडा
         """
-        return cls.random_element(cls.building_prefixes)
+        return self.random_element(self.building_prefixes)
diff --git a/faker/providers/address/nl_BE/__init__.py b/faker/providers/address/nl_BE/__init__.py
index b3c0d2ad..21b79ac7 100644
--- a/faker/providers/address/nl_BE/__init__.py
+++ b/faker/providers/address/nl_BE/__init__.py
@@ -792,10 +792,8 @@ class Provider(AddressProvider):
         "{{street_address}}\n{{postcode}}\n{{city}}","{{street_address}}\n{{postcode}} {{city}}",
     )
 
-    @classmethod
-    def province(cls):
-        return cls.random_element(cls.provinces)
+    def province(self):
+        return self.random_element(self.provinces)
 
-    @classmethod
-    def city(cls):
-        return cls.random_element(cls.cities)
+    def city(self):
+        return self.random_element(self.cities)
diff --git a/faker/providers/address/nl_NL/__init__.py b/faker/providers/address/nl_NL/__init__.py
index 112fde47..ece01dfb 100644
--- a/faker/providers/address/nl_NL/__init__.py
+++ b/faker/providers/address/nl_NL/__init__.py
@@ -583,10 +583,8 @@ class Provider(AddressProvider):
         "{{street_address}}\n{{postcode}}\n{{city}}",
     )
 
-    @classmethod
-    def province(cls):
-        return cls.random_element(cls.provinces)
+    def province(self):
+        return self.random_element(self.provinces)
 
-    @classmethod
-    def city(cls):
-        return cls.random_element(cls.cities)
+    def city(self):
+        return self.random_element(self.cities)
diff --git a/faker/providers/address/no_NO/__init__.py b/faker/providers/address/no_NO/__init__.py
index 3a2815b0..2259624d 100644
--- a/faker/providers/address/no_NO/__init__.py
+++ b/faker/providers/address/no_NO/__init__.py
@@ -31,15 +31,12 @@ class Provider(AddressProvider):
         'H': 0.05}
     postcode_formats = ('####',)
 
-    @classmethod
-    def building_number(cls):
-        suffix = cls.random_element(cls.building_number_suffixes)
-        return cls.numerify(cls.random_element(cls.building_number_formats)).replace('?', suffix)
+    def building_number(self):
+        suffix = self.random_element(self.building_number_suffixes)
+        return self.numerify(self.random_element(self.building_number_formats)).replace('?', suffix)
 
-    @classmethod
-    def city_suffix(cls):
-        return cls.random_element(cls.city_suffixes)
+    def city_suffix(self):
+        return self.random_element(self.city_suffixes)
 
-    @classmethod
-    def street_suffix(cls):
-        return cls.random_element(cls.street_suffixes)
+    def street_suffix(self):
+        return self.random_element(self.street_suffixes)
diff --git a/faker/providers/address/pl_PL/__init__.py b/faker/providers/address/pl_PL/__init__.py
index d59a0668..a1d0e73c 100644
--- a/faker/providers/address/pl_PL/__init__.py
+++ b/faker/providers/address/pl_PL/__init__.py
@@ -154,41 +154,36 @@ class Provider(AddressProvider):
         "{{street_address}}\n{{postcode}} {{city}}",
     )
 
-    @classmethod
-    def street_prefix(cls):
+    def street_prefix(self):
         """
         Randomly returns a street prefix
         :example 'aleja'
         """
-        return cls.random_element(cls.street_prefixes)
+        return self.random_element(self.street_prefixes)
 
-    @classmethod
-    def street_prefix_short(cls):
+    def street_prefix_short(self):
         """
         Randomly returns an abbreviation of the street prefix.
         :example 'al.'
         """
-        return cls.random_element(cls.street_prefixes)[:2]+'.'
+        return self.random_element(self.street_prefixes)[:2]+'.'
 
-    @classmethod
-    def street_name(cls):
+    def street_name(self):
         """
         Randomly returns a street name
         :example 'Wróblewskiego'
         """
-        return cls.random_element(cls.streets)
+        return self.random_element(self.streets)
 
-    @classmethod
-    def city(cls):
+    def city(self):
         """
         Randomly returns a street name
         :example 'Konin'
         """
-        return cls.random_element(cls.cities)
+        return self.random_element(self.cities)
 
-    @classmethod
-    def region(cls):
+    def region(self):
         """
         :example 'Wielkopolskie'
         """
-        return cls.random_element(cls.regions)
+        return self.random_element(self.regions)
diff --git a/faker/providers/address/pt_BR/__init__.py b/faker/providers/address/pt_BR/__init__.py
index bacf1ed3..c46fcc76 100644
--- a/faker/providers/address/pt_BR/__init__.py
+++ b/faker/providers/address/pt_BR/__init__.py
@@ -201,43 +201,38 @@ class Provider(AddressProvider):
         ('SE', 'Sergipe'), ('TO', 'Tocantins')
     )
 
-    @classmethod
-    def street_prefix(cls):
+    def street_prefix(self):
         """
         :example 'rua'
         """
-        return cls.random_element(cls.street_prefixes)
+        return self.random_element(self.street_prefixes)
 
-    @classmethod
-    def estado(cls):
+    def estado(self):
         """
         Randomly returns a Brazilian State  ('sigla' , 'nome').
         :example ('MG' . 'Minas Gerais')
         """
-        return cls.random_element(cls.estados)
+        return self.random_element(self.estados)
 
-    @classmethod
-    def estado_nome(cls):
+    def estado_nome(self):
         """
         Randomly returns a Brazilian State Name
         :example 'Minas Gerais'
         """
-        return cls.estado()[1]
+        return self.estado()[1]
 
-    @classmethod
-    def estado_sigla(cls):
+    def estado_sigla(self):
         """
         Randomly returns the abbreviation of a Brazilian State
 
         :example 'MG'
         """
-        return cls.estado()[0]
+        return self.estado()[0]
 
-    @classmethod
-    def bairro(cls):
+    def bairro(self):
         """
         Randomly returns a bairro (neighborhood) name. The names were taken from the city of Belo Horizonte - Minas Gerais
 
         :example 'Serra'
         """
-        return cls.random_element(cls.bairros)
+        return self.random_element(self.bairros)
diff --git a/faker/providers/address/pt_PT/__init__.py b/faker/providers/address/pt_PT/__init__.py
index f4816f9c..19a8482b 100644
--- a/faker/providers/address/pt_PT/__init__.py
+++ b/faker/providers/address/pt_PT/__init__.py
@@ -117,16 +117,14 @@ class Provider(AddressProvider):
         'Wake Island', 'Wallis e Futuna', 'West Bank', 'Zâmbia', 'Zimbabué',
     )
 
-    @classmethod
-    def street_prefix(cls):
+    def street_prefix(self):
         """
         :example 'Rua'
         """
-        return cls.random_element(cls.street_prefixes)
+        return self.random_element(self.street_prefixes)
 
-    @classmethod
-    def city_name(cls):
+    def city_name(self):
         """
         :example Amora
         """
-        return cls.random_element(cls.cities)
+        return self.random_element(self.cities)
diff --git a/faker/providers/address/ru_RU/__init__.py b/faker/providers/address/ru_RU/__init__.py
index cd33b920..884364f1 100644
--- a/faker/providers/address/ru_RU/__init__.py
+++ b/faker/providers/address/ru_RU/__init__.py
@@ -254,14 +254,11 @@ class Provider(AddressProvider):
         'Ясный (Оренб.)', 'Яхрома', 'Яшалта', 'Яшкуль'
     )
 
-    @classmethod
-    def city_prefix(cls):
-        return cls.random_element(cls.city_prefixes)
+    def city_prefix(self):
+        return self.random_element(self.city_prefixes)
 
-    @classmethod
-    def city_name(cls):
-        return cls.random_element(cls.city_names)
+    def city_name(self):
+        return self.random_element(self.city_names)
 
-    @classmethod
-    def street_title(cls):
-        return cls.random_element(cls.street_titles)
+    def street_title(self):
+        return self.random_element(self.street_titles)
diff --git a/faker/providers/address/sk_SK/__init__.py b/faker/providers/address/sk_SK/__init__.py
index e7504809..830799e2 100644
--- a/faker/providers/address/sk_SK/__init__.py
+++ b/faker/providers/address/sk_SK/__init__.py
@@ -1141,22 +1141,17 @@ class Provider(AddressProvider):
         'Jemenská ľudovodemokratická republika', 'Jemenská arabská republika',
         'Socialistická federatívna republika Juhoslávia', 'Zairská republika', )
 
-    @classmethod
-    def street_suffix_short(cls):
-        return cls.random_element(cls.street_suffixes_short)
+    def street_suffix_short(self):
+        return self.random_element(self.street_suffixes_short)
 
-    @classmethod
-    def street_suffix_long(cls):
-        return cls.random_element(cls.street_suffixes_long)
+    def street_suffix_long(self):
+        return self.random_element(self.street_suffixes_long)
 
-    @classmethod
-    def city_name(cls):
-        return cls.random_element(cls.cities)
+    def city_name(self):
+        return self.random_element(self.cities)
 
-    @classmethod
-    def street_name(cls):
-        return cls.random_element(cls.streets)
+    def street_name(self):
+        return self.random_element(self.streets)
 
-    @classmethod
-    def state(cls):
-        return cls.random_element(cls.states)
+    def state(self):
+        return self.random_element(self.states)
diff --git a/faker/providers/address/sl_SI/__init__.py b/faker/providers/address/sl_SI/__init__.py
index ff11437c..4c033b42 100755
--- a/faker/providers/address/sl_SI/__init__.py
+++ b/faker/providers/address/sl_SI/__init__.py
@@ -501,14 +501,11 @@ class Provider(AddressProvider):
         "Združeni arabski emirati", "Zelenortski otoki",
     )
 
-    @classmethod
-    def city_name(cls):
-        return cls.random_element(cls.cities)
+    def city_name(self):
+        return self.random_element(self.cities)
 
-    @classmethod
-    def street_name(cls):
-        return cls.random_element(cls.streets)
+    def street_name(self):
+        return self.random_element(self.streets)
 
-    @classmethod
-    def state(cls):
-        return cls.random_element(cls.states)
+    def state(self):
+        return self.random_element(self.states)
diff --git a/faker/providers/address/sv_SE/__init__.py b/faker/providers/address/sv_SE/__init__.py
index 4987639f..790d9370 100644
--- a/faker/providers/address/sv_SE/__init__.py
+++ b/faker/providers/address/sv_SE/__init__.py
@@ -100,14 +100,11 @@ class Provider(AddressProvider):
         'Norrbottens län'
     )
 
-    @classmethod
-    def street_prefix(cls):
-        return cls.random_element(cls.street_prefixes)
+    def street_prefix(self):
+        return self.random_element(self.street_prefixes)
 
-    @classmethod
-    def city_name(cls):
-        return cls.random_element(cls.cities)
+    def city_name(self):
+        return self.random_element(self.cities)
 
-    @classmethod
-    def state(cls):
-        return cls.random_element(cls.states)
+    def state(self):
+        return self.random_element(self.states)
diff --git a/faker/providers/address/uk_UA/__init__.py b/faker/providers/address/uk_UA/__init__.py
index 8a54539c..6cc02ee4 100644
--- a/faker/providers/address/uk_UA/__init__.py
+++ b/faker/providers/address/uk_UA/__init__.py
@@ -1,8 +1,6 @@
 # coding=utf-8
 from __future__ import unicode_literals
 
-from random import randint
-
 from .. import Provider as AddressProvider
 
 
@@ -60,15 +58,12 @@ class Provider(AddressProvider):
     ]
     street_suffixes = ['узвіз']
 
-    @classmethod
-    def city_prefix(cls):
-        return cls.random_element(cls.city_prefixes)
+    def city_prefix(self):
+        return self.random_element(self.city_prefixes)
 
-    @classmethod
-    def postcode(cls):
+    def postcode(self):
         """The code consists of five digits (01000-99999)"""
-        return '{}{}'.format(randint(0, 10), randint(1000, 10000))
+        return '{}{}'.format(self.generator.random.randint(0, 10), self.generator.random.randint(1000, 10000))
 
-    @classmethod
-    def street_prefix(cls):
-        return cls.random_element(cls.street_prefixes)
+    def street_prefix(self):
+        return self.random_element(self.street_prefixes)
diff --git a/faker/providers/address/zh_CN/__init__.py b/faker/providers/address/zh_CN/__init__.py
index ff0e6d07..7286cf36 100644
--- a/faker/providers/address/zh_CN/__init__.py
+++ b/faker/providers/address/zh_CN/__init__.py
@@ -71,18 +71,14 @@ class Provider(AddressProvider):
         "也门", "南斯拉夫", "扎伊尔", "赞比亚", "桑给巴尔", "津巴布韦", "中华人民共和国", "中国",
     )
 
-    @classmethod
-    def building_number(cls):
-        return cls.lexify(cls.random_element(cls.building_number_formats))
+    def building_number(self):
+        return self.lexify(self.random_element(self.building_number_formats))
 
-    @classmethod
-    def city_name(cls):
-        return cls.random_element(cls.cities)
+    def city_name(self):
+        return self.random_element(self.cities)
 
-    @classmethod
-    def province(cls):
-        return cls.random_element(cls.provinces)
+    def province(self):
+        return self.random_element(self.provinces)
 
-    @classmethod
-    def district(cls):
-        return cls.random_element(cls.districts)
+    def district(self):
+        return self.random_element(self.districts)
diff --git a/faker/providers/address/zh_TW/__init__.py b/faker/providers/address/zh_TW/__init__.py
index 99ad4ade..af12e222 100644
--- a/faker/providers/address/zh_TW/__init__.py
+++ b/faker/providers/address/zh_TW/__init__.py
@@ -88,30 +88,23 @@ class Provider(AddressProvider):
                  "羅馬尼亞", "葉門", "俄羅斯", "尚比亞", "盧安達", "辛巴威",
                  "聖克里斯多福及尼維斯")
 
-    @classmethod
-    def secondary_address(cls):
-        return cls.numerify(cls.random_element(cls.secondary_address_formats))
+    def secondary_address(self):
+        return self.numerify(self.random_element(self.secondary_address_formats))
 
-    @classmethod
-    def building_number(cls):
-        return cls.numerify(cls.random_element(cls.building_number_formats))
+    def building_number(self):
+        return self.numerify(self.random_element(self.building_number_formats))
 
-    @classmethod
-    def street_name(cls):
-        return cls.random_element(cls.street_names)
+    def street_name(self):
+        return self.random_element(self.street_names)
 
-    @classmethod
-    def street_name_suffix(cls):
-        return cls.random_element(cls.street_suffixes)
+    def street_name_suffix(self):
+        return self.random_element(self.street_suffixes)
 
-    @classmethod
-    def city_name(cls):
-        return cls.random_element(cls.cities)
+    def city_name(self):
+        return self.random_element(self.cities)
 
-    @classmethod
-    def city_name_suffix(cls):
-        return cls.random_element(cls.city_suffixes)
+    def city_name_suffix(self):
+        return self.random_element(self.city_suffixes)
 
-    @classmethod
-    def section_number(cls):
-        return cls.numerify(cls.random_element(cls.section_formats))
+    def section_number(self):
+        return self.numerify(self.random_element(self.section_formats))
diff --git a/faker/providers/automotive/__init__.py b/faker/providers/automotive/__init__.py
index 692d59db..2287d909 100644
--- a/faker/providers/automotive/__init__.py
+++ b/faker/providers/automotive/__init__.py
@@ -8,10 +8,9 @@ import re
 
 class Provider(BaseProvider):
     license_formats = ()
-    
-    @classmethod
-    def license_plate(cls):
+
+    def license_plate(self):
         temp = re.sub(r'\?',
-            lambda x: cls.random_element(ascii_uppercase),
-            cls.random_element(cls.license_formats))
-        return cls.numerify(temp)
+            lambda x: self.random_element(ascii_uppercase),
+            self.random_element(self.license_formats))
+        return self.numerify(temp)
diff --git a/faker/providers/color/__init__.py b/faker/providers/color/__init__.py
index 30b271b9..ad314a61 100644
--- a/faker/providers/color/__init__.py
+++ b/faker/providers/color/__init__.py
@@ -157,27 +157,21 @@ class Provider(BaseProvider):
         'gray', 'yellow', 'fuchsia', 'aqua', 'white',
     )
 
-    @classmethod
-    def color_name(cls):
-        return cls.random_element(cls.all_colors.keys())
+    def color_name(self):
+        return self.random_element(self.all_colors.keys())
 
-    @classmethod
-    def safe_color_name(cls):
-        return cls.random_element(cls.safe_colors)
+    def safe_color_name(self):
+        return self.random_element(self.safe_colors)
 
-    @classmethod
-    def hex_color(cls):
-        return "#{0}".format(("%x" % cls.random_int(1, 16777215)).ljust(6, '0'))
+    def hex_color(self):
+        return "#{0}".format(("%x" % self.random_int(1, 16777215)).ljust(6, '0'))
 
-    @classmethod
-    def safe_hex_color(cls):
-        color = ("%x" % cls.random_int(0, 255)).ljust(3, '0')
+    def safe_hex_color(self):
+        color = ("%x" % self.random_int(0, 255)).ljust(3, '0')
         return "#{0}{0}{1}{1}{2}{2}".format(*color)
 
-    @classmethod
-    def rgb_color(cls):
-        return ','.join(map(str, (cls.random_int(0, 255) for _ in range(3))))
+    def rgb_color(self):
+        return ','.join(map(str, (self.random_int(0, 255) for _ in range(3))))
 
-    @classmethod
-    def rgb_css_color(cls):
-        return 'rgb(%s)' % ','.join(map(str, (cls.random_int(0, 255) for _ in range(3))))
+    def rgb_css_color(self):
+        return 'rgb(%s)' % ','.join(map(str, (self.random_int(0, 255) for _ in range(3))))
diff --git a/faker/providers/company/__init__.py b/faker/providers/company/__init__.py
index e5269d0d..459be68e 100644
--- a/faker/providers/company/__init__.py
+++ b/faker/providers/company/__init__.py
@@ -19,9 +19,8 @@ class Provider(BaseProvider):
         pattern = self.random_element(self.formats)
         return self.generator.parse(pattern)
 
-    @classmethod
-    def company_suffix(cls):
+    def company_suffix(self):
         """
         :example 'Ltd'
         """
-        return cls.random_element(cls.company_suffixes)
+        return self.random_element(self.company_suffixes)
diff --git a/faker/providers/company/fr_CH/__init__.py b/faker/providers/company/fr_CH/__init__.py
index 313e2853..6c1cafef 100644
--- a/faker/providers/company/fr_CH/__init__.py
+++ b/faker/providers/company/fr_CH/__init__.py
@@ -1,16 +1,12 @@
 # coding=utf-8
 from __future__ import unicode_literals
-
-from faker.generator import random
-
 from ..fr_FR import Provider as CompanyProvider
 
 
 class Provider(CompanyProvider):
     company_suffixes = ('SA', 'Sàrl.')
-    
-    @classmethod
-    def ide(cls):
+
+    def ide(self):
         """
         Generates a IDE number (9 digits).
         http://www.bfs.admin.ch/bfs/portal/fr/index/themen/00/05/blank/03/02.html
@@ -24,7 +20,7 @@ class Provider(CompanyProvider):
 
         while True:
             # create an array of first 8 elements initialized randomly
-            digits = random.sample(range(10), 8)
+            digits = self.generator.random.sample(range(10), 8)
             # sum those 8 digits according to (part of) the "modulo 11"
             sum = _checksum(digits)
             # determine the last digit to make it qualify the test
@@ -32,7 +28,7 @@ class Provider(CompanyProvider):
             if (control_number != 10):
                 digits.append(control_number)
                 break
-        
+
         digits = ''.join([str(digit) for digit in digits])
         # finally return our random but valid BSN
         return 'CHE-' + digits[0:3] + '.'\
@@ -41,4 +37,4 @@ class Provider(CompanyProvider):
     uid = ide
     # uid: german name for ide
     idi = ide
-    # idi: italian name for ide
\ No newline at end of file
+    # idi: italian name for ide
diff --git a/faker/providers/company/fr_FR/__init__.py b/faker/providers/company/fr_FR/__init__.py
index b6b98b27..3a0a2f22 100644
--- a/faker/providers/company/fr_FR/__init__.py
+++ b/faker/providers/company/fr_FR/__init__.py
@@ -35,26 +35,23 @@ class Provider(CompanyProvider):
 
     siren_format = "### ### ###"
 
-    @classmethod
-    def catch_phrase_noun(cls):
+    def catch_phrase_noun(self):
         """
         Returns a random catch phrase noun.
         """
-        return cls.random_element(cls.nouns)
+        return self.random_element(self.nouns)
 
-    @classmethod
-    def catch_phrase_attribute(cls):
+    def catch_phrase_attribute(self):
         """
         Returns a random catch phrase attribute.
         """
-        return cls.random_element(cls.attributes)
+        return self.random_element(self.attributes)
 
-    @classmethod
-    def catch_phrase_verb(cls):
+    def catch_phrase_verb(self):
         """
         Returns a random catch phrase verb.
         """
-        return cls.random_element(cls.verbs)
+        return self.random_element(self.verbs)
 
     def catch_phrase(self):
         """
@@ -75,14 +72,13 @@ class Provider(CompanyProvider):
     # An array containing string which should not appear twice in a catch phrase
     words_which_should_not_appear_twice = ('sécurité', 'simpl')
 
-    @classmethod
-    def _is_catch_phrase_valid(cls, catch_phrase):
+    def _is_catch_phrase_valid(self, catch_phrase):
         """
         Validates a french catch phrase.
 
         :param catch_phrase: The catch phrase to validate.
         """
-        for word in cls.words_which_should_not_appear_twice:
+        for word in self.words_which_should_not_appear_twice:
             # Fastest way to check if a piece of word does not appear twice.
             begin_pos = catch_phrase.find(word)
             end_pos = catch_phrase.find(word, begin_pos + 1)
@@ -91,15 +87,13 @@ class Provider(CompanyProvider):
 
         return True
 
-    @classmethod
-    def siren(cls):
+    def siren(self):
         """
         Generates a siren number (9 digits).
         """
-        return cls.numerify(cls.siren_format)
+        return self.numerify(self.siren_format)
 
-    @classmethod
-    def siret(cls, max_sequential_digits=2):
+    def siret(self, max_sequential_digits=2):
         """
         Generates a siret number (14 digits).
         It is in fact the result of the concatenation of a siren number (9 digits),
@@ -110,10 +104,5 @@ class Provider(CompanyProvider):
         if max_sequential_digits > 4 or max_sequential_digits <= 0:
             max_sequential_digits = 2
 
-        sequential_number = str(cls.random_number(max_sequential_digits)).zfill(4)
-        return cls.numerify(cls.siren() + ' ' + sequential_number + '#')
-
-
-
-
-
+        sequential_number = str(self.random_number(max_sequential_digits)).zfill(4)
+        return self.numerify(self.siren() + ' ' + sequential_number + '#')
diff --git a/faker/providers/company/hu_HU/__init__.py b/faker/providers/company/hu_HU/__init__.py
index 919e2cc8..3ace97c2 100644
--- a/faker/providers/company/hu_HU/__init__.py
+++ b/faker/providers/company/hu_HU/__init__.py
@@ -20,6 +20,5 @@ class Provider(CompanyProvider):
         'BT'
     )
 
-    @classmethod
-    def company_suffix(cls):
-        return cls.random_element(cls.company_suffixes)
+    def company_suffix(self):
+        return self.random_element(self.company_suffixes)
diff --git a/faker/providers/company/it_IT/__init__.py b/faker/providers/company/it_IT/__init__.py
index e4c0ecca..56336493 100644
--- a/faker/providers/company/it_IT/__init__.py
+++ b/faker/providers/company/it_IT/__init__.py
@@ -93,4 +93,4 @@ class Provider(CompanyProvider):
         for word_list in self.bsWords:
             result.append(self.random_element(word_list))
 
-        return " ".join(result)
\ No newline at end of file
+        return " ".join(result)
diff --git a/faker/providers/company/ja_JP/__init__.py b/faker/providers/company/ja_JP/__init__.py
index c0e2b18b..649fafad 100644
--- a/faker/providers/company/ja_JP/__init__.py
+++ b/faker/providers/company/ja_JP/__init__.py
@@ -10,6 +10,5 @@ class Provider(CompanyProvider):
 
     company_prefixes = ('株式会社', '有限会社', '合同会社')
 
-    @classmethod
-    def company_prefix(cls):
-        return cls.random_element(cls.company_prefixes)
+    def company_prefix(self):
+        return self.random_element(self.company_prefixes)
diff --git a/faker/providers/company/pl_PL/__init__.py b/faker/providers/company/pl_PL/__init__.py
index 719d7e9b..74802950 100644
--- a/faker/providers/company/pl_PL/__init__.py
+++ b/faker/providers/company/pl_PL/__init__.py
@@ -55,43 +55,40 @@ def company_vat_checksum(digits):
 
 class Provider(CompanyProvider):
 
-    @classmethod
-    def regon(cls):
+    def regon(self):
         """
         Returns 9 character Polish National Business Registry Number,
         Polish: Rejestr Gospodarki Narodowej - REGON.
 
         https://pl.wikipedia.org/wiki/REGON
         """
-        voivodeship_number = cls.random_int(0, 49) * 2 + 1
+        voivodeship_number = self.random_int(0, 49) * 2 + 1
         regon_digits = [int(voivodeship_number / 10), voivodeship_number % 10]
 
         for _ in range(6):
-            regon_digits.append(cls.random_digit())
+            regon_digits.append(self.random_digit())
 
         regon_digits.append(regon_checksum(regon_digits))
 
         return ''.join(str(digit) for digit in regon_digits)
 
-    @classmethod
-    def local_regon(cls):
+    def local_regon(self):
         """
         Returns 14 character Polish National Business Registry Number,
         local entity number.
 
         https://pl.wikipedia.org/wiki/REGON
         """
-        regon_digits = [int(digit) for digit in list(cls.regon())]
+        regon_digits = [int(digit) for digit in list(self.regon())]
 
         for _ in range(4):
-            regon_digits.append(cls.random_digit())
+            regon_digits.append(self.random_digit())
 
         regon_digits.append(local_regon_checksum(regon_digits))
 
         return ''.join(str(digit) for digit in regon_digits)
 
-    @classmethod
-    def company_vat(cls):
+    def company_vat(self):
         """
         Returns 10 character tax identification number,
         Polish: Numer identyfikacji podatkowej.
@@ -101,16 +98,16 @@ class Provider(CompanyProvider):
         vat_digits = []
 
         for _ in range(3):
-            vat_digits.append(cls.random_digit_not_null())
+            vat_digits.append(self.random_digit_not_null())
 
         for _ in range(6):
-            vat_digits.append(cls.random_digit())
+            vat_digits.append(self.random_digit())
 
         check_digit = company_vat_checksum(vat_digits)
 
         # in this case we must generate a tax number again, because check_digit cannot be 10
         if check_digit == 10:
-            return cls.company_vat()
+            return self.company_vat()
 
         vat_digits.append(check_digit)
 
diff --git a/faker/providers/company/pt_BR/__init__.py b/faker/providers/company/pt_BR/__init__.py
index 9bf4e519..6af6af2d 100644
--- a/faker/providers/company/pt_BR/__init__.py
+++ b/faker/providers/company/pt_BR/__init__.py
@@ -50,26 +50,23 @@ class Provider(CompanyProvider):
 
     company_suffixes = ('S/A', 'S.A.', 'Ltda.', '- ME', '- EI', 'e Filhos')
 
-    @classmethod
-    def catch_phrase_noun(cls):
+    def catch_phrase_noun(self):
         """
         Returns a random catch phrase noun.
         """
-        return cls.random_element(cls.nouns)
+        return self.random_element(self.nouns)
 
-    @classmethod
-    def catch_phrase_attribute(cls):
+    def catch_phrase_attribute(self):
         """
         Returns a random catch phrase attribute.
         """
-        return cls.random_element(cls.attributes)
+        return self.random_element(self.attributes)
 
-    @classmethod
-    def catch_phrase_verb(cls):
+    def catch_phrase_verb(self):
         """
         Returns a random catch phrase verb.
         """
-        return cls.random_element(cls.verbs)
+        return self.random_element(self.verbs)
 
     def catch_phrase(self):
         """
@@ -80,14 +77,12 @@ class Provider(CompanyProvider):
         catch_phrase = catch_phrase[0].upper() + catch_phrase[1:]
         return catch_phrase
 
-    @classmethod
-    def company_id(cls):
-        digits = cls.random_sample(range(10), 8) + [0, 0, 0, 1]
+    def company_id(self):
+        digits = self.random_sample(range(10), 8) + [0, 0, 0, 1]
         digits += company_id_checksum(digits)
         return ''.join(str(d) for d in digits)
 
-    @classmethod
-    def cnpj(cls):
-        digits = cls.company_id()
+    def cnpj(self):
+        digits = self.company_id()
         return '{}.{}.{}/{}-{}'.format(digits[:2], digits[2:5], digits[5:8],
                                        digits[8:12], digits[12:])
diff --git a/faker/providers/company/ru_RU/__init__.py b/faker/providers/company/ru_RU/__init__.py
index 99fe83a0..653e79e3 100644
--- a/faker/providers/company/ru_RU/__init__.py
+++ b/faker/providers/company/ru_RU/__init__.py
@@ -16,6 +16,5 @@ class Provider(CompanyProvider):
         'РАО', 'АО', 'ИП', 'НПО',
     )
 
-    @classmethod
-    def company_prefix(cls):
-        return cls.random_element(cls.company_prefixes)
+    def company_prefix(self):
+        return self.random_element(self.company_prefixes)
diff --git a/faker/providers/company/zh_CN/__init__.py b/faker/providers/company/zh_CN/__init__.py
index 9ea6c31b..fb989614 100644
--- a/faker/providers/company/zh_CN/__init__.py
+++ b/faker/providers/company/zh_CN/__init__.py
@@ -22,6 +22,5 @@ class Provider(CompanyProvider):
                         "东方峻景", "华成育卓", "趋势", "维涛", "通际名联"]
     company_suffixes = [n + "有限公司" for n in ["科技", "网络", "信息", "传媒"]]
 
-    @classmethod
-    def company_prefix(cls):
-        return cls.random_element(cls.company_prefixes)
+    def company_prefix(self):
+        return self.random_element(self.company_prefixes)
diff --git a/faker/providers/company/zh_TW/__init__.py b/faker/providers/company/zh_TW/__init__.py
index 489c476d..aaea5541 100644
--- a/faker/providers/company/zh_TW/__init__.py
+++ b/faker/providers/company/zh_TW/__init__.py
@@ -35,6 +35,5 @@ class Provider(CompanyProvider):
 
     company_suffixes = ("", "有限公司", "股份有限公司", "資訊有限公司")
 
-    @classmethod
-    def company_prefix(cls):
-        return cls.random_element(cls.company_prefixes)
+    def company_prefix(self):
+        return self.random_element(self.company_prefixes)
diff --git a/faker/providers/credit_card/__init__.py b/faker/providers/credit_card/__init__.py
index 69ecd5bc..a683f1c0 100644
--- a/faker/providers/credit_card/__init__.py
+++ b/faker/providers/credit_card/__init__.py
@@ -2,7 +2,6 @@
 from __future__ import unicode_literals
 from collections import OrderedDict
 
-from faker.providers.date_time import Provider as DateTimeProvider
 from .. import BaseProvider
 
 
@@ -46,24 +45,21 @@ class Provider(BaseProvider):
     luhn_lookup = {'0': 0, '1': 2, '2': 4, '3': 6, '4': 8,
                    '5': 1, '6': 3, '7': 5, '8': 7, '9': 9}
 
-    @classmethod
-    def credit_card_provider(cls, card_type=None):
+    def credit_card_provider(self, card_type=None):
         """ Returns the provider's name of the credit card. """
         if card_type is None:
-            card_type = cls.random_element(cls.credit_card_types.keys())
-        return cls._credit_card_type(card_type).name
+            card_type = self.random_element(self.credit_card_types.keys())
+        return self._credit_card_type(card_type).name
 
-    @classmethod
-    def credit_card_number(cls, card_type=None):
+    def credit_card_number(self, card_type=None):
         """ Returns a valid credit card number. """
-        card = cls._credit_card_type(card_type)
-        prefix = cls.random_element(card.prefixes)
-        number = cls._generate_number(prefix, card.length)
+        card = self._credit_card_type(card_type)
+        prefix = self.random_element(card.prefixes)
+        number = self._generate_number(prefix, card.length)
         return number
 
-    @classmethod
-    def credit_card_expire(cls, start='now', end='+10y', date_format='%m/%y'):
-        expire_date = DateTimeProvider.date_time_between(start, end)
+    def credit_card_expire(self, start='now', end='+10y', date_format='%m/%y'):
+        expire_date = self.generator.date_time_between(start, end)
         return expire_date.strftime(date_format)
 
     def credit_card_full(self, card_type=None):
@@ -83,23 +79,20 @@ class Provider(BaseProvider):
 
         return self.generator.parse(tpl)
 
-    @classmethod
-    def credit_card_security_code(cls, card_type=None):
+    def credit_card_security_code(self, card_type=None):
         """ Returns a security code string. """
-        sec_len = cls._credit_card_type(card_type).security_code_length
-        return cls.numerify('#' * sec_len)
+        sec_len = self._credit_card_type(card_type).security_code_length
+        return self.numerify('#' * sec_len)
 
-    @classmethod
-    def _credit_card_type(cls, card_type=None):
+    def _credit_card_type(self, card_type=None):
         """ Returns a random credit card type instance. """
         if card_type is None:
-            card_type = cls.random_element(cls.credit_card_types.keys())
+            card_type = self.random_element(self.credit_card_types.keys())
         elif isinstance(card_type, CreditCard):
             return card_type
-        return cls.credit_card_types[card_type]
+        return self.credit_card_types[card_type]
 
-    @classmethod
-    def _generate_number(cls, prefix, length):
+    def _generate_number(self, prefix, length):
         """
         'prefix' is the start of the CC number as a string, any number of digits.
         'length' is the length of the CC number to generate. Typically 13 or 16
@@ -107,7 +100,7 @@ class Provider(BaseProvider):
         number = prefix
         # Generate random char digits
         number += '#' * (length - len(prefix) - 1)
-        number = cls.numerify(number)
+        number = self.numerify(number)
         reverse = number[::-1]
         # Calculate sum
         tot = 0
diff --git a/faker/providers/currency/__init__.py b/faker/providers/currency/__init__.py
index d2e32aa5..e95924f9 100644
--- a/faker/providers/currency/__init__.py
+++ b/faker/providers/currency/__init__.py
@@ -177,10 +177,8 @@ class Provider(BaseProvider):
         'TIT', 'VTC', 'XDN', 'XMR', 'XPM', 'XRP', 'ZEC',
     )
 
-    @classmethod
-    def currency_code(cls):
-        return cls.random_element(cls.currencies)
+    def currency_code(self):
+        return self.random_element(self.currencies)
 
-    @classmethod
-    def cryptocurrency_code(cls):
-        return cls.random_element(cls.cryptocurrencies)
+    def cryptocurrency_code(self):
+        return self.random_element(self.cryptocurrencies)
diff --git a/faker/providers/date_time/__init__.py b/faker/providers/date_time/__init__.py
index 15d5fd40..0d1eb6b0 100644
--- a/faker/providers/date_time/__init__.py
+++ b/faker/providers/date_time/__init__.py
@@ -11,7 +11,6 @@ from time import time
 from dateutil import relativedelta
 from dateutil.tz import tzlocal, tzutc
 
-from faker.generator import random
 from faker.utils.datetime_safe import date, datetime, real_date, real_datetime
 from faker.utils import is_string
 
@@ -247,88 +246,79 @@ class Provider(BaseProvider):
 
     regex = re.compile(timedelta_pattern)
 
-    @classmethod
-    def unix_time(cls):
+    def unix_time(self):
         """
         Get a timestamp between January 1, 1970 and now
         :example 1061306726
         """
-        return random.randint(0, int(time()))
+        return self.generator.random.randint(0, int(time()))
 
-    @classmethod
-    def time_delta(cls):
+    def time_delta(self):
         """
         Get a timedelta object
         """
-        ts = random.randint(0, int(time()))
+        ts = self.generator.random.randint(0, int(time()))
         return timedelta(seconds=ts)
 
-    @classmethod
-    def date_time(cls, tzinfo=None):
+    def date_time(self, tzinfo=None):
         """
         Get a datetime object for a date between January 1, 1970 and now
         :param tzinfo: timezone, instance of datetime.tzinfo subclass
         :example DateTime('2005-08-16 20:39:21')
         :return datetime
         """
-        return datetime.fromtimestamp(cls.unix_time(), tzinfo)
+        return datetime.fromtimestamp(self.unix_time(), tzinfo)
 
-    @classmethod
-    def date_time_ad(cls, tzinfo=None):
+    def date_time_ad(self, tzinfo=None):
         """
         Get a datetime object for a date between January 1, 001 and now
         :param tzinfo: timezone, instance of datetime.tzinfo subclass
         :example DateTime('1265-03-22 21:15:52')
         :return datetime
         """
-        ts = random.randint(-62135600400, int(time()))
+        ts = self.generator.random.randint(-62135600400, int(time()))
         # NOTE: using datetime.fromtimestamp(ts) directly will raise
         #       a "ValueError: timestamp out of range for platform time_t"
         #       on some platforms due to system C functions;
         #       see http://stackoverflow.com/a/10588133/2315612
         return datetime.fromtimestamp(0, tzinfo) + timedelta(seconds=ts)
 
-    @classmethod
-    def iso8601(cls, tzinfo=None):
+    def iso8601(self, tzinfo=None):
         """
         :param tzinfo: timezone, instance of datetime.tzinfo subclass
         :example '2003-10-21T16:05:52+0000'
         """
-        return cls.date_time(tzinfo).isoformat()
+        return self.date_time(tzinfo).isoformat()
 
-    @classmethod
-    def date(cls, pattern='%Y-%m-%d'):
+    def date(self, pattern='%Y-%m-%d'):
         """
         Get a date string between January 1, 1970 and now
         :param pattern format
         :example '2008-11-27'
         """
-        return cls.date_time().strftime(pattern)
+        return self.date_time().strftime(pattern)
 
-    @classmethod
-    def date_object(cls):
+    def date_object(self):
         """
         Get a date object between January 1, 1970 and now
         :example datetime.date(2016, 9, 20)
         """
-        return cls.date_time().date()
+        return self.date_time().date()
 
-    @classmethod
-    def time(cls, pattern='%H:%M:%S'):
+    def time(self, pattern='%H:%M:%S'):
         """
         Get a time string (24h format by default)
         :param pattern format
         :example '15:02:34'
         """
-        return cls.date_time().time().strftime(pattern)
+        return self.date_time().time().strftime(pattern)
 
-    @classmethod
-    def time_object(cls):
+    def time_object(self):
         """
         Get a time object
         :example datetime.time(15, 56, 56, 772876)
         """
-        return cls.date_time().time()
+        return self.date_time().time()
 
     @classmethod
     def _parse_date_string(cls, value):
@@ -377,8 +367,7 @@ class Provider(BaseProvider):
             return datetime_to_timestamp(now + timedelta(text))
         raise ParseError("Invalid format for date '{0}'".format(text))
 
-    @classmethod
-    def date_time_between(cls, start_date='-30y', end_date='now', tzinfo=None):
+    def date_time_between(self, start_date='-30y', end_date='now', tzinfo=None):
         """
         Get a DateTime object based on a random date between two given dates.
         Accepts date strings that can be recognized by strtotime().
@@ -389,13 +378,12 @@ class Provider(BaseProvider):
         :example DateTime('1999-02-02 11:42:52')
         :return DateTime
         """
-        start_date = cls._parse_date_time(start_date, tzinfo=tzinfo)
-        end_date = cls._parse_date_time(end_date, tzinfo=tzinfo)
-        timestamp = random.randint(start_date, end_date)
+        start_date = self._parse_date_time(start_date, tzinfo=tzinfo)
+        end_date = self._parse_date_time(end_date, tzinfo=tzinfo)
+        timestamp = self.generator.random.randint(start_date, end_date)
         return datetime(1970, 1, 1,tzinfo=tzinfo) + timedelta(seconds=timestamp)
 
-    @classmethod
-    def future_datetime(cls, end_date='+30d', tzinfo=None):
+    def future_datetime(self, end_date='+30d', tzinfo=None):
         """
         Get a DateTime object based on a random date between 1 second form now
         and a given date.
@@ -406,12 +394,11 @@ class Provider(BaseProvider):
         :example DateTime('1999-02-02 11:42:52')
         :return DateTime
         """
-        return cls.date_time_between(
+        return self.date_time_between(
             start_date='+1s', end_date=end_date, tzinfo=tzinfo,
         )
 
-    @classmethod
-    def future_date(cls, end_date='+30d', tzinfo=None):
+    def future_date(self, end_date='+30d', tzinfo=None):
         """
         Get a Date object based on a random date between 1 day from now and a
         given date.
@@ -422,12 +409,11 @@ class Provider(BaseProvider):
         :example DateTime('1999-02-02 11:42:52')
         :return DateTime
         """
-        return cls.date_time_between(
+        return self.date_time_between(
             start_date='+1d', end_date=end_date, tzinfo=tzinfo,
         ).date()
 
-    @classmethod
-    def past_datetime(cls, start_date='-30d', tzinfo=None):
+    def past_datetime(self, start_date='-30d', tzinfo=None):
         """
         Get a DateTime object based on a random date between a given date and 1
         second ago.
@@ -438,12 +424,11 @@ class Provider(BaseProvider):
         :example DateTime('1999-02-02 11:42:52')
         :return DateTime
         """
-        return cls.date_time_between(
+        return self.date_time_between(
             start_date=start_date, end_date='-1s', tzinfo=tzinfo,
         )
 
-    @classmethod
-    def past_date(cls, start_date='-30d', tzinfo=None):
+    def past_date(self, start_date='-30d', tzinfo=None):
         """
         Get a Date object based on a random date between a given date and 1 day
         ago.
@@ -454,12 +439,11 @@ class Provider(BaseProvider):
         :example DateTime('1999-02-02 11:42:52')
         :return DateTime
         """
-        return cls.date_time_between(
+        return self.date_time_between(
             start_date=start_date, end_date='-1d', tzinfo=tzinfo,
         ).date()
 
-    @classmethod
-    def date_time_between_dates(cls, datetime_start=None, datetime_end=None, tzinfo=None):
+    def date_time_between_dates(self, datetime_start=None, datetime_end=None, tzinfo=None):
         """
         Takes two DateTime objects and returns a random datetime between the two
         given datetimes.
@@ -477,7 +461,7 @@ class Provider(BaseProvider):
         if datetime_end is None:
             datetime_end = datetime.now(tzinfo)
 
-        timestamp = random.randint(
+        timestamp = self.generator.random.randint(
             datetime_to_timestamp(datetime_start),
             datetime_to_timestamp(datetime_end),
         )
@@ -488,8 +472,7 @@ class Provider(BaseProvider):
             pick = datetime.fromtimestamp(timestamp, tzinfo)
         return pick
 
-    @classmethod
-    def date_time_this_century(cls, before_now=True, after_now=False, tzinfo=None):
+    def date_time_this_century(self, before_now=True, after_now=False, tzinfo=None):
         """
         Gets a DateTime object for the current century.
 
@@ -504,16 +487,15 @@ class Provider(BaseProvider):
         next_century_start = datetime(this_century_start.year + 100, 1, 1, tzinfo=tzinfo)
 
         if before_now and after_now:
-            return cls.date_time_between_dates(this_century_start, next_century_start, tzinfo)
+            return self.date_time_between_dates(this_century_start, next_century_start, tzinfo)
         elif not before_now and after_now:
-            return cls.date_time_between_dates(now, next_century_start, tzinfo)
+            return self.date_time_between_dates(now, next_century_start, tzinfo)
         elif not after_now and before_now:
-            return cls.date_time_between_dates(this_century_start, now, tzinfo)
+            return self.date_time_between_dates(this_century_start, now, tzinfo)
         else:
             return now
 
-    @classmethod
-    def date_time_this_decade(cls, before_now=True, after_now=False, tzinfo=None):
+    def date_time_this_decade(self, before_now=True, after_now=False, tzinfo=None):
         """
         Gets a DateTime object for the decade year.
 
@@ -528,16 +510,15 @@ class Provider(BaseProvider):
         next_decade_start = datetime(this_decade_start.year + 10, 1, 1, tzinfo=tzinfo)
 
         if before_now and after_now:
-            return cls.date_time_between_dates(this_decade_start, next_decade_start, tzinfo)
+            return self.date_time_between_dates(this_decade_start, next_decade_start, tzinfo)
         elif not before_now and after_now:
-            return cls.date_time_between_dates(now, next_decade_start, tzinfo)
+            return self.date_time_between_dates(now, next_decade_start, tzinfo)
         elif not after_now and before_now:
-            return cls.date_time_between_dates(this_decade_start, now, tzinfo)
+            return self.date_time_between_dates(this_decade_start, now, tzinfo)
         else:
             return now
 
-    @classmethod
-    def date_time_this_year(cls, before_now=True, after_now=False, tzinfo=None):
+    def date_time_this_year(self, before_now=True, after_now=False, tzinfo=None):
         """
         Gets a DateTime object for the current year.
 
@@ -552,16 +533,15 @@ class Provider(BaseProvider):
         next_year_start = datetime(now.year + 1, 1, 1, tzinfo=tzinfo)
 
         if before_now and after_now:
-            return cls.date_time_between_dates(this_year_start, next_year_start, tzinfo)
+            return self.date_time_between_dates(this_year_start, next_year_start, tzinfo)
         elif not before_now and after_now:
-            return cls.date_time_between_dates(now, next_year_start, tzinfo)
+            return self.date_time_between_dates(now, next_year_start, tzinfo)
         elif not after_now and before_now:
-            return cls.date_time_between_dates(this_year_start, now, tzinfo)
+            return self.date_time_between_dates(this_year_start, now, tzinfo)
         else:
             return now
 
-    @classmethod
-    def date_time_this_month(cls, before_now=True, after_now=False, tzinfo=None):
+    def date_time_this_month(self, before_now=True, after_now=False, tzinfo=None):
         """
         Gets a DateTime object for the current month.
 
@@ -576,36 +556,35 @@ class Provider(BaseProvider):
 
         next_month_start = this_month_start + relativedelta.relativedelta(months=1)
         if before_now and after_now:
-            return cls.date_time_between_dates(this_month_start, next_month_start, tzinfo)
+            return self.date_time_between_dates(this_month_start, next_month_start, tzinfo)
         elif not before_now and after_now:
-            return cls.date_time_between_dates(now, next_month_start, tzinfo)
+            return self.date_time_between_dates(now, next_month_start, tzinfo)
         elif not after_now and before_now:
-            return cls.date_time_between_dates(this_month_start, now, tzinfo)
+            return self.date_time_between_dates(this_month_start, now, tzinfo)
         else:
             return now
 
-    @classmethod
-    def time_series(cls, start_date='-30d', end_date='now', precision=None, distrib=None, tzinfo=None):
+    def time_series(self, start_date='-30d', end_date='now', precision=None, distrib=None, tzinfo=None):
         """
         Returns a generator yielding tuples of ``(<datetime>, <value>)``.
 
         The data points will start at ``start_date``, and be at every time interval specified by
         ``precision``.
-
         ``distrib`` is a callable that accepts ``<datetime>`` and returns ``<value>``
+
         """
-        start_date = cls._parse_date_time(start_date, tzinfo=tzinfo)
-        end_date = cls._parse_date_time(end_date, tzinfo=tzinfo)
+        start_date = self._parse_date_time(start_date, tzinfo=tzinfo)
+        end_date = self._parse_date_time(end_date, tzinfo=tzinfo)
 
         if end_date < start_date:
             raise ValueError("`end_date` must be greater than `start_date`.")
 
         if precision is None:
             precision = (end_date - start_date) / 30
-        precision = cls._parse_timedelta(precision)
 
+        precision = self._parse_timedelta(precision)
         if distrib is None:
-            distrib = lambda dt: random.uniform(0, precision)  # noqa
+            distrib = lambda dt: self.generator.random.uniform(0, precision)  # noqa
 
         if not callable(distrib):
             raise ValueError("`distrib` must be a callable. Got {} instead.".format(distrib))
@@ -616,37 +595,29 @@ class Provider(BaseProvider):
             dt = timestamp_to_datetime(datapoint, tzinfo)
             yield (dt, distrib(dt))
 
-    @classmethod
-    def am_pm(cls):
-        return cls.date('%p')
+    def am_pm(self):
+        return self.date('%p')
 
-    @classmethod
-    def day_of_month(cls):
-        return cls.date('%d')
+    def day_of_month(self):
+        return self.date('%d')
 
-    @classmethod
-    def day_of_week(cls):
-        return cls.date('%A')
+    def day_of_week(self):
+        return self.date('%A')
 
-    @classmethod
-    def month(cls):
-        return cls.date('%m')
+    def month(self):
+        return self.date('%m')
 
-    @classmethod
-    def month_name(cls):
-        return cls.date('%B')
+    def month_name(self):
+        return self.date('%B')
 
-    @classmethod
-    def year(cls):
-        return cls.date('%Y')
+    def year(self):
+        return self.date('%Y')
 
-    @classmethod
-    def century(cls):
+    def century(self):
         """
         :example 'XVII'
         """
-        return cls.random_element(cls.centuries)
+        return self.random_element(self.centuries)
 
-    @classmethod
-    def timezone(cls):
-        return random.choice(cls.random_element(cls.countries)['timezones'])
+    def timezone(self):
+        return self.generator.random.choice(self.random_element(self.countries)['timezones'])
diff --git a/faker/providers/date_time/fr_FR/__init__.py b/faker/providers/date_time/fr_FR/__init__.py
index 063dd961..fbf1a9d9 100644
--- a/faker/providers/date_time/fr_FR/__init__.py
+++ b/faker/providers/date_time/fr_FR/__init__.py
@@ -6,9 +6,8 @@ from .. import Provider as DateTimeProvider
 
 class Provider(DateTimeProvider):
 
-    @classmethod
-    def day_of_week(cls):
-        day = cls.date('%w')
+    def day_of_week(self):
+        day = self.date('%w')
         DAY_NAMES = {
             "0": "Dimanche",
             "1": "Lundi",
@@ -20,9 +19,8 @@ class Provider(DateTimeProvider):
         }
         return DAY_NAMES[day]
 
-    @classmethod
-    def month_name(cls):
-        month = cls.month()
+    def month_name(self):
+        month = self.month()
         MONTH_NAMES = {
             "01": "Janvier",
             "02": "Février",
diff --git a/faker/providers/date_time/hr_HR/__init__.py b/faker/providers/date_time/hr_HR/__init__.py
index f001112d..53c3ccbe 100644
--- a/faker/providers/date_time/hr_HR/__init__.py
+++ b/faker/providers/date_time/hr_HR/__init__.py
@@ -6,9 +6,8 @@ from .. import Provider as DateTimeProvider
 
 class Provider(DateTimeProvider):
 
-    @classmethod
-    def day_of_week(cls):
-        day = cls.date('%w')
+    def day_of_week(self):
+        day = self.date('%w')
         DAY_NAMES = {
             "0": "Nedjelja",
             "1": "Ponedjeljak",
@@ -20,9 +19,8 @@ class Provider(DateTimeProvider):
         }
         return DAY_NAMES[day]
 
-    @classmethod
-    def month_name(cls):
-        month = cls.month()
+    def month_name(self):
+        month = self.month()
         MONTH_NAMES = {
             "01": "Siječanj",
             "02": "Veljača",
diff --git a/faker/providers/date_time/hu_HU/__init__.py b/faker/providers/date_time/hu_HU/__init__.py
index 29e2114b..7b87d97c 100644
--- a/faker/providers/date_time/hu_HU/__init__.py
+++ b/faker/providers/date_time/hu_HU/__init__.py
@@ -5,9 +5,8 @@ from .. import Provider as DateTimeProvider
 
 class Provider(DateTimeProvider):
 
-    @classmethod
-    def day_of_week(cls):
-        day = cls.date('%w')
+    def day_of_week(self):
+        day = self.date('%w')
         DAY_NAMES = {
             "0": "hétfő",
             "1": "kedd",
@@ -20,9 +19,8 @@ class Provider(DateTimeProvider):
 
         return DAY_NAMES[day]
 
-    @classmethod
-    def month_name(cls):
-        month = cls.month()
+    def month_name(self):
+        month = self.month()
         MONTH_NAMES = {
             "01": "január",
             "02": "február",
diff --git a/faker/providers/date_time/ko_KR/__init__.py b/faker/providers/date_time/ko_KR/__init__.py
index f3333b74..58737e55 100644
--- a/faker/providers/date_time/ko_KR/__init__.py
+++ b/faker/providers/date_time/ko_KR/__init__.py
@@ -6,9 +6,8 @@ from .. import Provider as DateTimeProvider
 
 class Provider(DateTimeProvider):
 
-    @classmethod
-    def day_of_week(cls):
-        day = cls.date('%w')
+    def day_of_week(self):
+        day = self.date('%w')
         DAY_NAMES = {
             "0": "일요일",
             "1": "월요일",
@@ -20,9 +19,8 @@ class Provider(DateTimeProvider):
         }
         return DAY_NAMES[day]
 
-    @classmethod
-    def month_name(cls):
-        month = cls.month()
+    def month_name(self):
+        month = self.month()
         MONTH_NAMES = {
             "01": "1월",
             "02": "2월",
diff --git a/faker/providers/date_time/pl_PL/__init__.py b/faker/providers/date_time/pl_PL/__init__.py
index 595c3ce3..d2b3cc8e 100644
--- a/faker/providers/date_time/pl_PL/__init__.py
+++ b/faker/providers/date_time/pl_PL/__init__.py
@@ -32,12 +32,10 @@ class Provider(DateTimeProvider):
         '12': 'grudzień'
     }
 
-    @classmethod
-    def day_of_week(cls):
-        day = cls.date('%w')
-        return cls.DAY_NAMES[day]
-
-    @classmethod
-    def month_name(cls):
-        month = cls.month()
-        return cls.MONTH_NAMES[month]
+    def day_of_week(self):
+        day = self.date('%w')
+        return self.DAY_NAMES[day]
+
+    def month_name(self):
+        month = self.month()
+        return self.MONTH_NAMES[month]
diff --git a/faker/providers/date_time/ru_RU/__init__.py b/faker/providers/date_time/ru_RU/__init__.py
index f7ee4c4d..0802eea0 100644
--- a/faker/providers/date_time/ru_RU/__init__.py
+++ b/faker/providers/date_time/ru_RU/__init__.py
@@ -6,9 +6,8 @@ from .. import Provider as DateTimeProvider
 
 class Provider(DateTimeProvider):
 
-    @classmethod
-    def day_of_week(cls):
-        day = cls.date('%w')
+    def day_of_week(self):
+        day = self.date('%w')
         DAY_NAMES = {
             "0": "Воскресенье",
             "1": "Понедельник",
@@ -20,9 +19,8 @@ class Provider(DateTimeProvider):
         }
         return DAY_NAMES[day]
 
-    @classmethod
-    def month_name(cls):
-        month = cls.month()
+    def month_name(self):
+        month = self.month()
         MONTH_NAMES = {
             "01": "Январь",
             "02": "Февраль",
@@ -38,4 +36,3 @@ class Provider(DateTimeProvider):
             "12": "Декабрь",
         }
         return MONTH_NAMES[month]
-
diff --git a/faker/providers/date_time/sl_SI/__init__.py b/faker/providers/date_time/sl_SI/__init__.py
index 1bbd7646..34b6c8b7 100644
--- a/faker/providers/date_time/sl_SI/__init__.py
+++ b/faker/providers/date_time/sl_SI/__init__.py
@@ -6,9 +6,8 @@ from .. import Provider as DateTimeProvider
 
 class Provider(DateTimeProvider):
 
-    @classmethod
-    def day_of_week(cls):
-        day = cls.date('%w')
+    def day_of_week(self):
+        day = self.date('%w')
         DAY_NAMES = {
             "0": "Nedelja",
             "1": "Ponedeljek",
@@ -20,9 +19,8 @@ class Provider(DateTimeProvider):
         }
         return DAY_NAMES[day]
 
-    @classmethod
-    def month_name(cls):
-        month = cls.month()
+    def month_name(self):
+        month = self.month()
         MONTH_NAMES = {
             "01": "Januar",
             "02": "Februar",
diff --git a/faker/providers/file/__init__.py b/faker/providers/file/__init__.py
index 4f4c14ce..a82357e6 100644
--- a/faker/providers/file/__init__.py
+++ b/faker/providers/file/__init__.py
@@ -3,7 +3,6 @@ from __future__ import unicode_literals
 from collections import OrderedDict
 
 from .. import BaseProvider
-from ..lorem.la import Provider as WordProvider
 
 
 class Provider(BaseProvider):
@@ -176,41 +175,37 @@ class Provider(BaseProvider):
         ("video", video_file_extensions),
     ))
 
-    @classmethod
-    def mime_type(cls, category=None):
+    def mime_type(self, category=None):
         """
         :param category: application|audio|image|message|model|multipart|text|video
         """
-        category = category if category else cls.random_element(list(cls.mime_types.keys()))
-        return cls.random_element(cls.mime_types[category])
+        category = category if category else self.random_element(list(self.mime_types.keys()))
+        return self.random_element(self.mime_types[category])
 
-    @classmethod
-    def file_name(cls, category=None, extension=None):
+    def file_name(self, category=None, extension=None):
         """
         :param category: audio|image|office|text|video
         :param extension: file extension
         """
-        extension = extension if extension else cls.file_extension(category)
-        filename = WordProvider.word()
+        extension = extension if extension else self.file_extension(category)
+        filename = self.generator.word()
         return '{0}.{1}'.format(filename, extension)
 
-    @classmethod
-    def file_extension(cls, category=None):
+    def file_extension(self, category=None):
         """
         :param category: audio|image|office|text|video
         """
-        category = category if category else cls.random_element(list(cls.file_extensions.keys()))
-        return cls.random_element(cls.file_extensions[category])
+        category = category if category else self.random_element(list(self.file_extensions.keys()))
+        return self.random_element(self.file_extensions[category])
 
-    @classmethod
-    def file_path(cls, depth=1, category=None, extension=None):
+    def file_path(self, depth=1, category=None, extension=None):
         """
         :param category: audio|image|office|text|video
         :param extension: file extension
         :param depth: depth of the file (depth >= 0)
         """
-        file = Provider.file_name(category, extension)
+        file = self.file_name(category, extension)
         path = "/{0}".format(file)
         for d in range(0, depth):
-            path = "/{0}{1}".format(WordProvider.word(), path)
+            path = "/{0}{1}".format(self.generator.word(), path)
         return path
diff --git a/faker/providers/internet/__init__.py b/faker/providers/internet/__init__.py
index e3dfc0ad..a2d5a48d 100644
--- a/faker/providers/internet/__init__.py
+++ b/faker/providers/internet/__init__.py
@@ -4,8 +4,8 @@ from .. import BaseProvider
 
 from ipaddress import ip_address, ip_network, IPV4LENGTH, IPV6LENGTH
 
-from faker.generator import random
-from faker.providers.lorem.la import Provider as Lorem
+# from faker.generator import random
+# from faker.providers.lorem.la import Provider as Lorem
 from faker.utils.decorators import slugify, slugify_unicode
 
 
@@ -85,9 +85,8 @@ class Provider(BaseProvider):
     def company_email(self):
         return self.user_name() + '@' + self.domain_name()
 
-    @classmethod
-    def free_email_domain(cls):
-        return cls.random_element(cls.free_email_domains)
+    def free_email_domain(self):
+        return self.random_element(self.free_email_domains)
 
     @slugify_unicode
     def user_name(self):
@@ -130,60 +129,55 @@ class Provider(BaseProvider):
 
     def ipv4(self, network=False):
         """Produce a random IPv4 address or network with a valid CIDR"""
-        address = str(ip_address(random.randint(
+        address = str(ip_address(self.generator.random.randint(
             0, (2 ** IPV4LENGTH) - 1)))
         if network:
-            address += '/' + str(random.randint(0, IPV4LENGTH))
+            address += '/' + str(self.generator.random.randint(0, IPV4LENGTH))
             address = str(ip_network(address, strict=False))
         return address
 
     def ipv6(self, network=False):
         """Produce a random IPv6 address or network with a valid CIDR"""
-        address = str(ip_address(random.randint(
+        address = str(ip_address(self.generator.random.randint(
             2 ** IPV4LENGTH, (2 ** IPV6LENGTH) - 1)))
         if network:
-            address += '/' + str(random.randint(0, IPV6LENGTH))
+            address += '/' + str(self.generator.random.randint(0, IPV6LENGTH))
             address = str(ip_network(address, strict=False))
         return address
 
     def mac_address(self):
-        mac = [random.randint(0x00, 0xff) for i in range(0, 6)]
+        mac = [self.generator.random.randint(0x00, 0xff) for i in range(0, 6)]
         return ":".join(map(lambda x: "%02x" % x, mac))
 
-    @classmethod
-    def uri_page(cls):
-        return cls.random_element(cls.uri_pages)
+    def uri_page(self):
+        return self.random_element(self.uri_pages)
 
-    @classmethod
-    def uri_path(cls, deep=None):
-        deep = deep if deep else random.randint(1, 3)
+    def uri_path(self, deep=None):
+        deep = deep if deep else self.generator.random.randint(1, 3)
         return "/".join(
-            [cls.random_element(cls.uri_paths) for _ in range(0, deep)]
+            [self.random_element(self.uri_paths) for _ in range(0, deep)]
         )
 
-    @classmethod
-    def uri_extension(cls):
-        return cls.random_element(cls.uri_extensions)
+    def uri_extension(self):
+        return self.random_element(self.uri_extensions)
 
     def uri(self):
         pattern = self.random_element(self.uri_formats)
         return self.generator.parse(pattern)
 
-    @classmethod
     @slugify
-    def slug(cls, value=None):
+    def slug(self, value=None):
         """Django algorithm"""
         if value is None:
-            value = Lorem.text(20)
+            value = self.generator.text(20)
         return value
 
-    @classmethod
-    def image_url(cls, width=None, height=None):
+    def image_url(self, width=None, height=None):
         """
         Returns URL to placeholder image
         Example: http://placehold.it/640x480
         """
-        width_ = width or cls.random_int(max=1024)
-        height_ = height or cls.random_int(max=1024)
-        placeholder_url = cls.random_element(cls.image_placeholder_services)
+        width_ = width or self.random_int(max=1024)
+        height_ = height or self.random_int(max=1024)
+        placeholder_url = self.random_element(self.image_placeholder_services)
         return placeholder_url.format(width=width_, height=height_)
diff --git a/faker/providers/job/__init__.py b/faker/providers/job/__init__.py
index 5c0d7158..de636fe4 100644
--- a/faker/providers/job/__init__.py
+++ b/faker/providers/job/__init__.py
@@ -647,6 +647,5 @@ class Provider(BaseProvider):
         "Youth worker",
     )
 
-    @classmethod
-    def job(cls):
-        return cls.random_element(cls.jobs)
+    def job(self):
+        return self.random_element(self.jobs)
diff --git a/faker/providers/lorem/__init__.py b/faker/providers/lorem/__init__.py
index 094fcbdf..c0cfd824 100644
--- a/faker/providers/lorem/__init__.py
+++ b/faker/providers/lorem/__init__.py
@@ -26,8 +26,7 @@ class Provider(BaseProvider):
     word_connector = ' '
     sentence_punctuation = '.'
 
-    @classmethod
-    def word(cls, ext_word_list=None):
+    def word(self, ext_word_list=None):
         """
         :returns: A random word, eg: 'lorem'
 
@@ -37,11 +36,10 @@ class Provider(BaseProvider):
         :rtype: str
         """
         if ext_word_list:
-            return cls.random_element(ext_word_list)
-        return cls.random_element(cls.word_list)
+            return self.random_element(ext_word_list)
+        return self.random_element(self.word_list)
 
-    @classmethod
-    def words(cls, nb=3, ext_word_list=None):
+    def words(self, nb=3, ext_word_list=None):
         """
         :returns: An array of random words. for example: ['Lorem', 'ipsum', 'dolor']
 
@@ -52,10 +50,9 @@ class Provider(BaseProvider):
 
         :rtype: list
         """
-        return [cls.word(ext_word_list) for _ in range(0, nb)]
+        return [self.word(ext_word_list) for _ in range(0, nb)]
 
-    @classmethod
-    def sentence(cls, nb_words=6, variable_nb_words=True, ext_word_list=None):
+    def sentence(self, nb_words=6, variable_nb_words=True, ext_word_list=None):
         """
         Generate a random sentence
         :example 'Lorem ipsum dolor sit amet.'
@@ -73,15 +70,14 @@ class Provider(BaseProvider):
             return ''
 
         if variable_nb_words:
-            nb_words = cls.randomize_nb_elements(nb_words)
+            nb_words = self.randomize_nb_elements(nb_words)
 
-        words = cls.words(nb=nb_words, ext_word_list=ext_word_list)
+        words = self.words(nb=nb_words, ext_word_list=ext_word_list)
         words[0] = words[0].title()
 
-        return cls.word_connector.join(words) + cls.sentence_punctuation
+        return self.word_connector.join(words) + self.sentence_punctuation
 
-    @classmethod
-    def sentences(cls, nb=3, ext_word_list=None):
+    def sentences(self, nb=3, ext_word_list=None):
         """
         Generate an array of sentences
         :example ['Lorem ipsum dolor sit amet.', 'Consectetur adipisicing eli.']
@@ -93,10 +89,9 @@ class Provider(BaseProvider):
 
         :rtype: list
         """
-        return [cls.sentence(ext_word_list=ext_word_list) for _ in range(0, nb)]
+        return [self.sentence(ext_word_list=ext_word_list) for _ in range(0, nb)]
 
-    @classmethod
-    def paragraph(cls, nb_sentences=3, variable_nb_sentences=True, ext_word_list=None):
+    def paragraph(self, nb_sentences=3, variable_nb_sentences=True, ext_word_list=None):
         """
         :returns: A single paragraph. For example: 'Sapiente sunt omnis. Ut
             pariatur ad autem ducimus et. Voluptas rem voluptas sint modi dolorem amet.'
@@ -115,16 +110,15 @@ class Provider(BaseProvider):
             return ''
 
         if variable_nb_sentences:
-            nb_sentences = cls.randomize_nb_elements(nb_sentences)
+            nb_sentences = self.randomize_nb_elements(nb_sentences)
 
-        para = cls.word_connector.join(cls.sentences(
+        para = self.word_connector.join(self.sentences(
             nb_sentences, ext_word_list=ext_word_list
         ))
 
         return para
 
-    @classmethod
-    def paragraphs(cls, nb=3, ext_word_list=None):
+    def paragraphs(self, nb=3, ext_word_list=None):
         """
         Generate an array of paragraphs
         :example [paragraph1, paragraph2, paragraph3]
@@ -135,10 +129,9 @@ class Provider(BaseProvider):
         :rtype: list
         """
 
-        return [cls.paragraph(ext_word_list=ext_word_list) for _ in range(0, nb)]
+        return [self.paragraph(ext_word_list=ext_word_list) for _ in range(0, nb)]
 
-    @classmethod
-    def text(cls, max_nb_chars=200, ext_word_list=None):
+    def text(self, max_nb_chars=200, ext_word_list=None):
         """
         Generate a text string.
         Depending on the ``max_nb_chars, returns a string made of words, sentences, or paragraphs.
@@ -160,20 +153,20 @@ class Provider(BaseProvider):
                 size = 0
                 # determine how many words are needed to reach the $max_nb_chars once;
                 while size < max_nb_chars:
-                    word = (cls.word_connector if size else '') + cls.word(ext_word_list=ext_word_list)
+                    word = (self.word_connector if size else '') + self.word(ext_word_list=ext_word_list)
                     text.append(word)
                     size += len(word)
                 text.pop()
             text[0] = text[0][0].upper() + text[0][1:]
             last_index = len(text) - 1
-            text[last_index] += cls.sentence_punctuation
+            text[last_index] += self.sentence_punctuation
         elif max_nb_chars < 100:
             # join sentences
             while not text:
                 size = 0
                 # determine how many sentences are needed to reach the $max_nb_chars once
                 while size < max_nb_chars:
-                    sentence = (cls.word_connector if size else '') + cls.sentence(ext_word_list=ext_word_list)
+                    sentence = (self.word_connector if size else '') + self.sentence(ext_word_list=ext_word_list)
                     text.append(sentence)
                     size += len(sentence)
                 text.pop()
@@ -183,7 +176,7 @@ class Provider(BaseProvider):
                 size = 0
                 # determine how many paragraphs are needed to reach the $max_nb_chars once
                 while size < max_nb_chars:
-                    paragraph = ('\n' if size else '') + cls.paragraph(ext_word_list=ext_word_list)
+                    paragraph = ('\n' if size else '') + self.paragraph(ext_word_list=ext_word_list)
                     text.append(paragraph)
                     size += len(paragraph)
                 text.pop()
diff --git a/faker/providers/misc/__init__.py b/faker/providers/misc/__init__.py
index 679f84b9..f3bf86c8 100644
--- a/faker/providers/misc/__init__.py
+++ b/faker/providers/misc/__init__.py
@@ -7,9 +7,6 @@ import uuid
 import os
 import sys
 
-from faker.generator import random
-from faker.providers.date_time import Provider as DatetimeProvider
-
 from .. import BaseProvider
 
 
@@ -74,81 +71,71 @@ class Provider(BaseProvider):
         'zu': ('ZA',)
     }
 
-    @classmethod
-    def boolean(cls, chance_of_getting_true=50):
-        return random.randint(1, 100) <= chance_of_getting_true
+    def boolean(self, chance_of_getting_true=50):
+        return self.generator.random.randint(1, 100) <= chance_of_getting_true
 
-    @classmethod
-    def null_boolean(cls):
+    def null_boolean(self):
         return {
             0: None,
             1: True,
             -1: False
-        }[random.randint(-1, 1)]
+        }[self.generator.random.randint(-1, 1)]
 
-    @classmethod
-    def binary(cls, length=(1 * 1024 * 1024)):
+    def binary(self, length=(1 * 1024 * 1024)):
         """ Returns random binary blob.
 
         Default blob size is 1 Mb.
         """
-        blob = [random.randrange(256) for o in range(length)]
+        blob = [self.generator.random.randrange(256) for o in range(length)]
         return bytes(blob) if sys.version_info[0] >= 3 else bytearray(blob)
 
-    @classmethod
-    def md5(cls, raw_output=False):
+    def md5(self, raw_output=False):
         """
         Calculates the md5 hash of a given string
         :example 'cfcd208495d565ef66e7dff9f98764da'
         """
-        res = hashlib.md5(str(random.random()).encode('utf-8'))
+        res = hashlib.md5(str(self.generator.random.random()).encode('utf-8'))
         if raw_output:
             return res.digest()
         return res.hexdigest()
 
-    @classmethod
-    def sha1(cls, raw_output=False):
+    def sha1(self, raw_output=False):
         """
         Calculates the sha1 hash of a given string
         :example 'b5d86317c2a144cd04d0d7c03b2b02666fafadf2'
         """
-        res = hashlib.sha1(str(random.random()).encode('utf-8'))
+        res = hashlib.sha1(str(self.generator.random.random()).encode('utf-8'))
         if raw_output:
             return res.digest()
         return res.hexdigest()
 
-    @classmethod
-    def sha256(cls, raw_output=False):
+    def sha256(self, raw_output=False):
         """
         Calculates the sha256 hash of a given string
         :example '85086017559ccc40638fcde2fecaf295e0de7ca51b7517b6aebeaaf75b4d4654'
         """
-        res = hashlib.sha256(str(random.random()).encode('utf-8'))
+        res = hashlib.sha256(str(self.generator.random.random()).encode('utf-8'))
         if raw_output:
             return res.digest()
         return res.hexdigest()
 
-    @classmethod
-    def locale(cls):
-        language_code = cls.language_code()
-        return language_code + '_' + cls.random_element(
-            cls.language_locale_codes[language_code]
+    def locale(self):
+        language_code = self.language_code()
+        return language_code + '_' + self.random_element(
+            Provider.language_locale_codes[language_code]
         )
 
-    @classmethod
-    def language_code(cls):
-        return cls.random_element(cls.language_locale_codes.keys())
+    def language_code(self):
+        return self.random_element(Provider.language_locale_codes.keys())
 
-    @classmethod
-    def uuid4(cls):
+    def uuid4(self):
         """
         Generates a random UUID4 string.
         """
         # Based on http://stackoverflow.com/q/41186818
-        return str(uuid.UUID(int=random.getrandbits(128)))
+        return str(uuid.UUID(int=self.generator.random.getrandbits(128)))
 
-    @classmethod
-    def password(cls, length=10, special_chars=True, digits=True, upper_case=True, lower_case=True):
+    def password(self, length=10, special_chars=True, digits=True, upper_case=True, lower_case=True):
         """
         Generates a random password.
         @param length: Integer. Length of a password
@@ -161,27 +148,27 @@ class Provider(BaseProvider):
         choices = ""
         required_tokens = []
         if special_chars:
-            required_tokens.append(random.choice("!@#$%^&*()_+"))
+            required_tokens.append(self.generator.random.choice("!@#$%^&*()_+"))
             choices += "!@#$%^&*()_+"
         if digits:
-            required_tokens.append(random.choice(string.digits))
+            required_tokens.append(self.generator.random.choice(string.digits))
             choices += string.digits
         if upper_case:
-            required_tokens.append(random.choice(string.ascii_uppercase))
+            required_tokens.append(self.generator.random.choice(string.ascii_uppercase))
             choices += string.ascii_uppercase
         if lower_case:
-            required_tokens.append(random.choice(string.ascii_lowercase))
+            required_tokens.append(self.generator.random.choice(string.ascii_lowercase))
             choices += string.ascii_lowercase
 
         assert len(required_tokens) <= length, "Required length is shorter than required characters"
 
         # Generate a first version of the password
-        chars = [random.choice(choices) for x in range(length)]
+        chars = [self.generator.random.choice(choices) for x in range(length)]
 
         # Pick some unique locations
         random_indexes = set()
         while len(random_indexes) < len(required_tokens):
-            random_indexes.add(random.randint(0, len(chars) - 1))
+            random_indexes.add(self.generator.random.randint(0, len(chars) - 1))
 
         # Replace them with the required characters
         for i, index in enumerate(random_indexes):
diff --git a/faker/providers/person/__init__.py b/faker/providers/person/__init__.py
index 73eb33da..242ee0ea 100644
--- a/faker/providers/person/__init__.py
+++ b/faker/providers/person/__init__.py
@@ -17,13 +17,11 @@ class Provider(BaseProvider):
         pattern = self.random_element(self.formats)
         return self.generator.parse(pattern)
 
-    @classmethod
-    def first_name(cls):
-        return cls.random_element(cls.first_names)
+    def first_name(self):
+        return self.random_element(self.first_names)
 
-    @classmethod
-    def last_name(cls):
-        return cls.random_element(cls.last_names)
+    def last_name(self):
+        return self.random_element(self.last_names)
 
     def name_male(self):
         if hasattr(self, 'formats_male'):
@@ -41,68 +39,58 @@ class Provider(BaseProvider):
         pattern = self.random_element(formats)
         return self.generator.parse(pattern)
 
-    @classmethod
-    def first_name_male(cls):
-        if hasattr(cls, 'first_names_male'):
-            return cls.random_element(cls.first_names_male)
-        return cls.first_name()
-
-    @classmethod
-    def first_name_female(cls):
-        if hasattr(cls, 'first_names_female'):
-            return cls.random_element(cls.first_names_female)
-        return cls.first_name()
-
-    @classmethod
-    def last_name_male(cls):
-        if hasattr(cls, 'last_names_male'):
-            return cls.random_element(cls.last_names_male)
-        return cls.last_name()
-
-    @classmethod
-    def last_name_female(cls):
-        if hasattr(cls, 'last_names_female'):
-            return cls.random_element(cls.last_names_female)
-        return cls.last_name()
-
-    @classmethod
-    def prefix(cls):
-        if hasattr(cls, 'prefixes'):
-            return cls.random_element(cls.prefixes)
-        if hasattr(cls, 'prefixes_male') and hasattr(cls, 'prefixes_female'):
-            prefixes = cls.random_element((cls.prefixes_male, cls.prefixes_female))
-            return cls.random_element(prefixes)
+    def first_name_male(self):
+        if hasattr(self, 'first_names_male'):
+            return self.random_element(self.first_names_male)
+        return self.first_name()
+
+    def first_name_female(self):
+        if hasattr(self, 'first_names_female'):
+            return self.random_element(self.first_names_female)
+        return self.first_name()
+
+    def last_name_male(self):
+        if hasattr(self, 'last_names_male'):
+            return self.random_element(self.last_names_male)
+        return self.last_name()
+
+    def last_name_female(self):
+        if hasattr(self, 'last_names_female'):
+            return self.random_element(self.last_names_female)
+        return self.last_name()
+
+    def prefix(self):
+        if hasattr(self, 'prefixes'):
+            return self.random_element(self.prefixes)
+        if hasattr(self, 'prefixes_male') and hasattr(self, 'prefixes_female'):
+            prefixes = self.random_element((self.prefixes_male, self.prefixes_female))
+            return self.random_element(prefixes)
         return ''
 
-    @classmethod
-    def prefix_male(cls):
-        if hasattr(cls, 'prefixes_male'):
-            return cls.random_element(cls.prefixes_male)
-        return cls.prefix()
-
-    @classmethod
-    def prefix_female(cls):
-        if hasattr(cls, 'prefixes_female'):
-            return cls.random_element(cls.prefixes_female)
-        return cls.prefix()
-
-    @classmethod
-    def suffix(cls):
-        if hasattr(cls, 'suffixes'):
-            return cls.random_element(cls.suffixes)
-        if hasattr(cls, 'suffixes_male') and hasattr(cls, 'suffixes_female'):
-            suffixes = cls.random_element((cls.suffixes_male, cls.suffixes_female))
-            return cls.random_element(suffixes)
+    def prefix_male(self):
+        if hasattr(self, 'prefixes_male'):
+            return self.random_element(self.prefixes_male)
+        return self.prefix()
+
+    def prefix_female(self):
+        if hasattr(self, 'prefixes_female'):
+            return self.random_element(self.prefixes_female)
+        return self.prefix()
+
+    def suffix(self):
+        if hasattr(self, 'suffixes'):
+            return self.random_element(self.suffixes)
+        if hasattr(self, 'suffixes_male') and hasattr(self, 'suffixes_female'):
+            suffixes = self.random_element((self.suffixes_male, self.suffixes_female))
+            return self.random_element(suffixes)
         return ''
 
-    @classmethod
-    def suffix_male(cls):
-        if hasattr(cls, 'suffixes_male'):
-            return cls.random_element(cls.suffixes_male)
-        return cls.suffix()
-
-    @classmethod
-    def suffix_female(cls):
-        if hasattr(cls, 'suffixes_female'):
-            return cls.random_element(cls.suffixes_female)
-        return cls.suffix()
+    def suffix_male(self):
+        if hasattr(self, 'suffixes_male'):
+            return self.random_element(self.suffixes_male)
+        return self.suffix()
+
+    def suffix_female(self):
+        if hasattr(self, 'suffixes_female'):
+            return self.random_element(self.suffixes_female)
+        return self.suffix()
diff --git a/faker/providers/person/et_EE/__init__.py b/faker/providers/person/et_EE/__init__.py
index 538897c4..8cdb5aa7 100644
--- a/faker/providers/person/et_EE/__init__.py
+++ b/faker/providers/person/et_EE/__init__.py
@@ -157,34 +157,26 @@ class Provider(PersonProvider):
                       'Štšerbakov', 'Žukov', 'Žuravljov')
     last_names = set(last_names_est + last_names_rus)
 
-    @classmethod
-    def first_name_male_est(cls):
-        return cls.random_element(cls.first_names_male_est)
+    def first_name_male_est(self):
+        return self.random_element(self.first_names_male_est)
 
-    @classmethod
-    def first_name_female_est(cls):
-        return cls.random_element(cls.first_names_female_est)
+    def first_name_female_est(self):
+        return self.random_element(self.first_names_female_est)
 
-    @classmethod
-    def first_name_male_rus(cls):
-        return cls.random_element(cls.first_names_male_rus)
+    def first_name_male_rus(self):
+        return self.random_element(self.first_names_male_rus)
 
-    @classmethod
-    def first_name_female_rus(cls):
-        return cls.random_element(cls.first_names_female_rus)
+    def first_name_female_rus(self):
+        return self.random_element(self.first_names_female_rus)
 
-    @classmethod
-    def first_name_est(cls):
-        return cls.random_element(cls.first_names_est)
+    def first_name_est(self):
+        return self.random_element(self.first_names_est)
 
-    @classmethod
-    def first_name_rus(cls):
-        return cls.random_element(cls.first_names_rus)
+    def first_name_rus(self):
+        return self.random_element(self.first_names_rus)
 
-    @classmethod
-    def last_name_est(cls):
-        return cls.random_element(cls.last_names_est)
+    def last_name_est(self):
+        return self.random_element(self.last_names_est)
 
-    @classmethod
-    def last_name_rus(cls):
-        return cls.random_element(cls.last_names_rus)
+    def last_name_rus(self):
+        return self.random_element(self.last_names_rus)
diff --git a/faker/providers/person/fa_IR/__init__.py b/faker/providers/person/fa_IR/__init__.py
index 063f7580..0a1bbeb4 100644
--- a/faker/providers/person/fa_IR/__init__.py
+++ b/faker/providers/person/fa_IR/__init__.py
@@ -58,14 +58,14 @@ class Provider(PersonProvider):
         'امیرعباس', 'نیما', 'علیرضا', 'عرشیا', 'محمدامین', 'مبین', 'محمدحسین',
         'یوسف', 'رضا', 'احسان', 'علی اصغر', 'آرین', 'امیرمهدی', 'محمدیاسین',
         'ماهان', 'عباس', 'پارسا', 'حسام', 'یاسین', 'علی رضا', 'ایلیا',
-        'علی اكبر', 'محمدجواد', 'بنیامین', 
+        'علی اكبر', 'محمدجواد', 'بنیامین',
         # http://www.sabteahval.ir/Upload/Modules/Contents/asset100/name/p1393.htm
         'اميرعلي', 'ايليا', 'محمد', 'محمدپارسا', 'محمد', 'پرهام', 'ابوالفضل',
-        'سبحان', 'اميرحسين', 'آرتين', 'علي', 'آرمين', 'حسين', 'عرفان', 'اميرمحمد', 
+        'سبحان', 'اميرحسين', 'آرتين', 'علي', 'آرمين', 'حسين', 'عرفان', 'اميرمحمد',
          'آريا', 'اميرعباس', 'محمدياسين', 'محمدمهدي', 'متين', 'محمدرضا', 'دانيال',
          'مهدي', 'ساميار', 'محمدحسين', 'احسان', 'اميررضا', 'آرين', 'عليرضا', 'سينا',
         'محمدامين', 'آراد', 'علي', 'سجاد', 'طاها', 'حسام', 'رضا', 'يوسف', 'ماهان', 'آرش',
-        'مبين', 'ياسين', 'علي', 'اميرمهدي', 'عباس', 'پارسا', 'محمدعلي', 'کيان', 
+        'مبين', 'ياسين', 'علي', 'اميرمهدي', 'عباس', 'پارسا', 'محمدعلي', 'کيان',
         'محمدجواد', 'بنيامين',
     )
 
@@ -92,6 +92,5 @@ class Provider(PersonProvider):
     prefixes_male = ('جناب آقای', 'جناب آقای دکتر')
     prefixes_female = ('سرکار خانم', 'سرکار خانم دکتر')
 
-    @classmethod
-    def suffix(cls):
+    def suffix(self):
         return ''
diff --git a/faker/providers/person/hu_HU/__init__.py b/faker/providers/person/hu_HU/__init__.py
index 755816d2..540990fd 100644
--- a/faker/providers/person/hu_HU/__init__.py
+++ b/faker/providers/person/hu_HU/__init__.py
@@ -147,15 +147,12 @@ class Provider(PersonProvider):
 
     prefixes = OrderedDict((('Dr.', 0.95), ('Prof. Dr.', 0.05)))
 
+    def first_name_male_abbreviated(self):
+        if hasattr(self, 'first_names_male'):
+            return self.random_element(self.first_names_male)[0] + "."
+        return self.first_name()[0]
 
-    @classmethod
-    def first_name_male_abbreviated(cls):
-        if hasattr(cls, 'first_names_male'):
-            return cls.random_element(cls.first_names_male)[0] + "."
-        return cls.first_name()[0]
-
-    @classmethod
-    def first_name_female_abbreviated(cls):
-        if hasattr(cls, 'first_names_female'):
-            return cls.random_element(cls.first_names_female)[0] + "."
-        return cls.first_name()[0]
+    def first_name_female_abbreviated(self):
+        if hasattr(self, 'first_names_female'):
+            return self.random_element(self.first_names_female)[0] + "."
+        return self.first_name()[0]
diff --git a/faker/providers/person/ja_JP/__init__.py b/faker/providers/person/ja_JP/__init__.py
index e7477216..fc4ac68e 100644
--- a/faker/providers/person/ja_JP/__init__.py
+++ b/faker/providers/person/ja_JP/__init__.py
@@ -131,27 +131,23 @@ class Provider(PersonProvider):
         pattern = self.random_element(self.kana_formats)
         return self.generator.parse(pattern)
 
-    @classmethod
-    def first_kana_name(cls):
+    def first_kana_name(self):
         '''
         @example 'アキラ'
         '''
-        return cls.random_element(cls.first_kana_names)
+        return self.random_element(self.first_kana_names)
 
-    @classmethod
-    def first_kana_name_female(cls):
-        return cls.random_element(cls.first_kana_names_female)
+    def first_kana_name_female(self):
+        return self.random_element(self.first_kana_names_female)
 
-    @classmethod
-    def first_kana_name_male(cls):
-        return cls.random_element(cls.first_kana_names_male)
+    def first_kana_name_male(self):
+        return self.random_element(self.first_kana_names_male)
 
-    @classmethod
-    def last_kana_name(cls):
+    def last_kana_name(self):
         '''
         @example 'アオタ'
         '''
-        return cls.random_element(cls.last_kana_names)
+        return self.random_element(self.last_kana_names)
 
     def romanized_name(self):
         '''
@@ -160,24 +156,20 @@ class Provider(PersonProvider):
         pattern = self.random_element(self.romanized_formats)
         return self.generator.parse(pattern)
 
-    @classmethod
-    def first_romanized_name(cls):
+    def first_romanized_name(self):
         '''
         @example 'Akira'
         '''
-        return cls.random_element(cls.first_romanized_names)
+        return self.random_element(self.first_romanized_names)
 
-    @classmethod
-    def first_romanized_name_female(cls):
-        return cls.random_element(cls.first_romanized_names_female)
+    def first_romanized_name_female(self):
+        return self.random_element(self.first_romanized_names_female)
 
-    @classmethod
-    def first_romanized_name_male(cls):
-        return cls.random_element(cls.first_romanized_names_male)
+    def first_romanized_name_male(self):
+        return self.random_element(self.first_romanized_names_male)
 
-    @classmethod
-    def last_romanized_name(cls):
+    def last_romanized_name(self):
         '''
         @example 'Aota'
         '''
-        return cls.random_element(cls.last_romanized_names)
+        return self.random_element(self.last_romanized_names)
diff --git a/faker/providers/person/pl_PL/__init__.py b/faker/providers/person/pl_PL/__init__.py
index 94d49150..9e87d642 100644
--- a/faker/providers/person/pl_PL/__init__.py
+++ b/faker/providers/person/pl_PL/__init__.py
@@ -542,12 +542,10 @@ class Provider(PersonProvider):
 
     first_names = first_names_male + first_names_female
 
-    @classmethod
-    def last_name(cls):
-        return cls.random_element(cls.unisex_last_names)
+    def last_name(self):
+        return self.random_element(self.unisex_last_names)
 
-    @classmethod
-    def identity_card_number(cls):
+    def identity_card_number(self):
         """
         Returns 9 character Polish Identity Card Number,
         Polish: Numer Dowodu Osobistego.
@@ -560,13 +558,13 @@ class Provider(PersonProvider):
         identity = []
 
         for _ in range(3):
-            identity.append(cls.random_letter().upper())
+            identity.append(self.random_letter().upper())
 
         # it will be overwritten by a checksum
         identity.append(0)
 
         for _ in range(5):
-            identity.append(cls.random_digit())
+            identity.append(self.random_digit())
 
         identity[3] = checksum_identity_card_number(identity)
 
diff --git a/faker/providers/person/pt_PT/__init__.py b/faker/providers/person/pt_PT/__init__.py
index edd6291a..558764cc 100644
--- a/faker/providers/person/pt_PT/__init__.py
+++ b/faker/providers/person/pt_PT/__init__.py
@@ -70,6 +70,5 @@ class Provider(PersonProvider):
 
     prefixes = ('de', 'da', 'do')
 
-    @classmethod
-    def prefix(cls):
-        return cls.random_element(cls.prefixes)
+    def prefix(self):
+        return self.random_element(self.prefixes)
diff --git a/faker/providers/person/ru_RU/__init__.py b/faker/providers/person/ru_RU/__init__.py
index 747db9bf..62844c27 100644
--- a/faker/providers/person/ru_RU/__init__.py
+++ b/faker/providers/person/ru_RU/__init__.py
@@ -259,18 +259,15 @@ class Provider(PersonProvider):
 
     prefixes_female = ('г-жа', 'тов.')
 
-    @classmethod
-    def middle_name(cls):
-        return cls.random_element(cls.middle_names)
+    def middle_name(self):
+        return self.random_element(self.middle_names)
 
-    @classmethod
-    def middle_name_male(cls):
-        if hasattr(cls, 'middle_names_male'):
-            return cls.random_element(cls.middle_names_male)
-        return cls.middle_name()
+    def middle_name_male(self):
+        if hasattr(self, 'middle_names_male'):
+            return self.random_element(self.middle_names_male)
+        return self.middle_name()
 
-    @classmethod
-    def middle_name_female(cls):
-        if hasattr(cls, 'middle_names_female'):
-            return cls.random_element(cls.middle_names_female)
-        return cls.middle_name()
+    def middle_name_female(self):
+        if hasattr(self, 'middle_names_female'):
+            return self.random_element(self.middle_names_female)
+        return self.middle_name()
diff --git a/faker/providers/person/zh_CN/__init__.py b/faker/providers/person/zh_CN/__init__.py
index 0b8c24d2..1185ac62 100644
--- a/faker/providers/person/zh_CN/__init__.py
+++ b/faker/providers/person/zh_CN/__init__.py
@@ -89,16 +89,14 @@ class Provider(PersonProvider):
         pattern = self.random_element(self.romanized_formats)
         return self.generator.parse(pattern)
 
-    @classmethod
-    def first_romanized_name(cls):
+    def first_romanized_name(self):
         '''
         @example 'Chao'
         '''
-        return cls.random_element(cls.first_romanized_names)
+        return self.random_element(self.first_romanized_names)
 
-    @classmethod
-    def last_romanized_name(cls):
+    def last_romanized_name(self):
         '''
         @example 'Chao'
         '''
-        return cls.random_element(cls.last_romanized_names)
+        return self.random_element(self.last_romanized_names)
diff --git a/faker/providers/person/zh_TW/__init__.py b/faker/providers/person/zh_TW/__init__.py
index 6c7e06d4..2ac11673 100644
--- a/faker/providers/person/zh_TW/__init__.py
+++ b/faker/providers/person/zh_TW/__init__.py
@@ -105,16 +105,14 @@ class Provider(PersonProvider):
         pattern = self.random_element(self.romanized_formats)
         return self.generator.parse(pattern)
 
-    @classmethod
-    def first_romanized_name(cls):
+    def first_romanized_name(self):
         '''
         @example 'Chao'
         '''
-        return cls.random_element(cls.first_romanized_names)
+        return self.random_element(self.first_romanized_names)
 
-    @classmethod
-    def last_romanized_name(cls):
+    def last_romanized_name(self):
         '''
         @example 'Chao'
         '''
-        return cls.random_element(cls.last_romanized_names)
+        return self.random_element(self.last_romanized_names)
diff --git a/faker/providers/phone_number/__init__.py b/faker/providers/phone_number/__init__.py
index ec963547..1af2d2d2 100644
--- a/faker/providers/phone_number/__init__.py
+++ b/faker/providers/phone_number/__init__.py
@@ -6,6 +6,5 @@ from .. import BaseProvider
 class Provider(BaseProvider):
     formats = ('###-###-###',)
 
-    @classmethod
-    def phone_number(cls):
-        return cls.numerify(cls.random_element(cls.formats))
+    def phone_number(self):
+        return self.numerify(self.random_element(self.formats))
diff --git a/faker/providers/phone_number/en_AU/__init__.py b/faker/providers/phone_number/en_AU/__init__.py
index 5378caa0..4796b32d 100644
--- a/faker/providers/phone_number/en_AU/__init__.py
+++ b/faker/providers/phone_number/en_AU/__init__.py
@@ -33,9 +33,8 @@ class Provider(PhoneNumberProvider):
         '+61.4##.###.###',
     )
 
-    @classmethod
-    def area_code(cls):
-        return cls.numerify(cls.random_element(
+    def area_code(self):
+        return self.numerify(self.random_element(
             ['2',
              '3',
              '7',
diff --git a/faker/providers/phone_number/zh_CN/__init__.py b/faker/providers/phone_number/zh_CN/__init__.py
index b00a0ace..d73dd514 100644
--- a/faker/providers/phone_number/zh_CN/__init__.py
+++ b/faker/providers/phone_number/zh_CN/__init__.py
@@ -10,6 +10,5 @@ class Provider(PhoneNumberProvider):
                             145, 133, 153, 180, 181, 189]
     formats = [str(i) + "########" for i in phonenumber_prefixes]
 
-    @classmethod
-    def phonenumber_prefix(cls):
-        return cls.random_element(cls.phonenumber_prefixes)
+    def phonenumber_prefix(self):
+        return self.random_element(self.phonenumber_prefixes)
diff --git a/faker/providers/python/__init__.py b/faker/providers/python/__init__.py
index f310b235..43ab08bc 100644
--- a/faker/providers/python/__init__.py
+++ b/faker/providers/python/__init__.py
@@ -5,9 +5,6 @@ from __future__ import unicode_literals
 from decimal import Decimal
 import sys
 
-from faker.providers.lorem.la import Provider as Lorem
-from faker.generator import random
-
 from .. import BaseProvider
 
 
@@ -20,12 +17,10 @@ else:
 
 
 class Provider(BaseProvider):
-    @classmethod
-    def pybool(cls):
-        return cls.random_int(0, 1) == 1
+    def pybool(self):
+        return self.random_int(0, 1) == 1
 
-    @classmethod
-    def pystr(cls, min_chars=None, max_chars=20):
+    def pystr(self, min_chars=None, max_chars=20):
         """
         Generates a random string of upper and lowercase letters.
         :type min_chars: int
@@ -33,13 +28,12 @@ class Provider(BaseProvider):
         :return: String. Random of random length between min and max characters.
         """
         if min_chars is None:
-            return "".join(cls.random_letter() for i in range(max_chars))
+            return "".join(self.random_letter() for i in range(max_chars))
         else:
             assert (max_chars >= min_chars), "Maximum length must be greater than or equal to minium length"
-            return "".join(cls.random_letter() for i in range(0, random.randint(min_chars, max_chars)))
+            return "".join(self.random_letter() for i in range(0, self.generator.random.randint(min_chars, max_chars)))
 
-    @classmethod
-    def pyfloat(cls, left_digits=None, right_digits=None, positive=False):
+    def pyfloat(self, left_digits=None, right_digits=None, positive=False):
         if left_digits is not None and left_digits < 0:
             raise ValueError('A float number cannot have less than 0 digits in its '
                              'integer part')
@@ -50,23 +44,21 @@ class Provider(BaseProvider):
             raise ValueError('A float number cannot have less than 0 digits in total')
 
         left_digits = left_digits if left_digits is not None else (
-            cls.random_int(1, sys.float_info.dig))
+            self.random_int(1, sys.float_info.dig))
         right_digits = right_digits if right_digits is not None else (
-            cls.random_int(0, sys.float_info.dig-left_digits))
-        sign = 1 if positive else cls.random_element((-1, 1))
+            self.random_int(0, sys.float_info.dig - left_digits))
+        sign = 1 if positive else self.random_element((-1, 1))
 
         return float("{0}.{1}".format(
-            sign * cls.random_number(left_digits),
-            cls.random_number(right_digits)
+            sign * self.random_number(left_digits),
+            self.random_number(right_digits)
         ))
 
-    @classmethod
-    def pyint(cls):
-        return cls.random_int()
+    def pyint(self):
+        return self.generator.random_int()
 
-    @classmethod
-    def pydecimal(cls, left_digits=None, right_digits=None, positive=False):
-        return Decimal(str(cls.pyfloat(left_digits, right_digits, positive)))
+    def pydecimal(self, left_digits=None, right_digits=None, positive=False):
+        return Decimal(str(self.pyfloat(left_digits, right_digits, positive)))
 
     def pytuple(self, nb_elements=10, variable_nb_elements=True, *value_types):
         return tuple(self.pyset(nb_elements, variable_nb_elements, *value_types))
@@ -116,7 +108,7 @@ class Provider(BaseProvider):
             nb_elements = self.randomize_nb_elements(nb_elements)
 
         return dict(zip(
-            Lorem.words(nb_elements),
+            self.generator.words(nb_elements),
             self._pyiterable(nb_elements, False, *value_types)
         ))
 
@@ -133,9 +125,9 @@ class Provider(BaseProvider):
         d = {}
         nd = {}
         for i in range(count):
-            d[Lorem.word()] = self._random_type(value_types)
+            d[self.generator.word()] = self._random_type(value_types)
             l.append(self._random_type(value_types))
-            nd[Lorem.word()] = {
+            nd[self.generator.word()] = {
                 i: self._random_type(value_types),
                 i + 1: [self._random_type(value_types), self._random_type(value_types), self._random_type(value_types)],
                 i + 2: {
diff --git a/faker/providers/ssn/__init__.py b/faker/providers/ssn/__init__.py
index d8e929ae..9a057e6b 100644
--- a/faker/providers/ssn/__init__.py
+++ b/faker/providers/ssn/__init__.py
@@ -8,6 +8,5 @@ from .. import BaseProvider
 class Provider(BaseProvider):
     ssn_formats = ("###-##-####",)
 
-    @classmethod
-    def ssn(cls):
-        return cls.bothify(cls.random_element(cls.ssn_formats))
+    def ssn(self):
+        return self.bothify(self.random_element(self.ssn_formats))
diff --git a/faker/providers/ssn/en_CA/__init__.py b/faker/providers/ssn/en_CA/__init__.py
index 0e920bc0..1f8c9ae6 100644
--- a/faker/providers/ssn/en_CA/__init__.py
+++ b/faker/providers/ssn/en_CA/__init__.py
@@ -1,18 +1,16 @@
 # coding=utf-8
 from __future__ import unicode_literals
 from .. import Provider as SsnProvider
-from faker.generator import random
 
 
 class Provider(SsnProvider):
 
     # in order to create a valid SIN we need to provide a number that passes a simple modified Luhn Algorithmn checksum
     # this function essentially reverses the checksum steps to create a random valid SIN (Social Insurance Number)
-    @classmethod
-    def ssn(cls):
+    def ssn(self):
 
         # create an array of 8 elements initialized randomly
-        digits = random.sample(range(10), 8)
+        digits = self.generator.random.sample(range(10), 8)
 
         # All of the digits must sum to a multiple of 10.
         # sum the first 8 and set 9th to the value to get to a multiple of 10
diff --git a/faker/providers/ssn/en_US/__init__.py b/faker/providers/ssn/en_US/__init__.py
index 424d4cfb..4357535c 100644
--- a/faker/providers/ssn/en_US/__init__.py
+++ b/faker/providers/ssn/en_US/__init__.py
@@ -5,16 +5,15 @@ from .. import Provider as BaseProvider
 
 class Provider(BaseProvider):
 
-    @classmethod
-    def ssn(cls):
+    def ssn(self):
         # Certain numbers are invalid for U.S. SSNs. The area (first 3 digits)
         # cannot be 666 or 900-999. The group number (middle digits) cannot be
         # 00. The serial (last 4 digits) cannot be 0000
-        area = BaseProvider.random_int(min=1, max=899)
+        area = self.random_int(min=1, max=899)
         if area == 666:
             area += 1
-        group = BaseProvider.random_int(1, 99)
-        serial = BaseProvider.random_int(1, 9999)
+        group = self.random_int(1, 99)
+        serial = self.random_int(1, 9999)
 
         ssn = "{0:03d}-{1:02d}-{2:04d}".format(area, group, serial)
         return ssn
diff --git a/faker/providers/ssn/et_EE/__init__.py b/faker/providers/ssn/et_EE/__init__.py
index f1181b54..6c5da83f 100644
--- a/faker/providers/ssn/et_EE/__init__.py
+++ b/faker/providers/ssn/et_EE/__init__.py
@@ -2,7 +2,6 @@
 
 from __future__ import unicode_literals
 from .. import Provider as SsnProvider
-from faker.generator import random
 import datetime
 import operator
 
@@ -35,8 +34,7 @@ class Provider(SsnProvider):
     scale1 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 1)
     scale2 = (3, 4, 5, 6, 7, 8, 9, 1, 2, 3)
 
-    @classmethod
-    def ssn(cls):
+    def ssn(self):
         """
         Returns 11 character Estonian personal identity code (isikukood, IK).
 
@@ -51,17 +49,17 @@ class Provider(SsnProvider):
 
         https://en.wikipedia.org/wiki/National_identification_number#Estonia
         """
-        age = datetime.timedelta(days=random.randrange(Provider.min_age,
-                                                       Provider.max_age))
+        age = datetime.timedelta(days=self.generator.random.randrange(self.min_age,
+                                                       self.max_age))
         birthday = datetime.date.today() - age
         if birthday.year < 2000:
-            ik = random.choice(('3', '4'))
+            ik = self.generator.random.choice(('3', '4'))
         elif birthday.year < 2100:
-            ik = random.choice(('5', '6'))
+            ik = self.generator.random.choice(('5', '6'))
         else:
-            ik = random.choice(('7', '8'))
+            ik = self.generator.random.choice(('7', '8'))
 
         ik += "%02d%02d%02d" % ((birthday.year % 100), birthday.month,
                                 birthday.day)
-        ik += str(random.randrange(0, 999)).zfill(3)
+        ik += str(self.generator.random.randrange(0, 999)).zfill(3)
         return ik + str(checksum([int(ch) for ch in ik]))
diff --git a/faker/providers/ssn/fi_FI/__init__.py b/faker/providers/ssn/fi_FI/__init__.py
index bba2c0b0..a440b002 100644
--- a/faker/providers/ssn/fi_FI/__init__.py
+++ b/faker/providers/ssn/fi_FI/__init__.py
@@ -2,14 +2,12 @@
 
 from __future__ import unicode_literals
 from .. import Provider as SsnProvider
-from faker.generator import random
 import datetime
 
 
 class Provider(SsnProvider):
 
-    @classmethod
-    def ssn(cls):
+    def ssn(self):
         """
         Returns 11 character Finnish personal identity code (Henkilötunnus,
         HETU, Swedish: Personbeteckning). Age of person is between 18 and 90
@@ -33,14 +31,14 @@ class Provider(SsnProvider):
 
         min_age = 18 * 365
         max_age = 90 * 365
-        age = datetime.timedelta(days=random.randrange(min_age, max_age))
+        age = datetime.timedelta(days=self.generator.random.randrange(min_age, max_age))
         birthday = datetime.date.today() - age
         hetu_date = "%02d%02d%s" % (birthday.day, birthday.month, str(birthday.year)[-2:])
         if birthday.year < 2000:
             separator = '-'
         else:
             separator = 'A'
-        suffix = str(random.randrange(2, 899)).zfill(3)
+        suffix = str(self.generator.random.randrange(2, 899)).zfill(3)
         checksum = _checksum(hetu_date + suffix)
         hetu = "".join([hetu_date, separator, suffix, checksum])
         return hetu
diff --git a/faker/providers/ssn/fr_CH/__init__.py b/faker/providers/ssn/fr_CH/__init__.py
index 732646cd..84f2bdcf 100644
--- a/faker/providers/ssn/fr_CH/__init__.py
+++ b/faker/providers/ssn/fr_CH/__init__.py
@@ -2,14 +2,12 @@
 
 from __future__ import unicode_literals
 from .. import Provider as SsnProvider
-from faker.generator import random
 
 
 class Provider(SsnProvider):
     ssn_formats = ("###.####.####.##",)
 
-    @classmethod
-    def ssn(cls):
+    def ssn(self):
         """
         Returns a 13 digits Swiss SSN named AHV (German) or
                                             AVS (French and Italian)
@@ -22,7 +20,7 @@ class Provider(SsnProvider):
 
         digits = [7, 5, 6]
         # create an array of first 9 elements initialized randomly
-        digits += random.sample(range(10), 9)
+        digits += self.generator.random.sample(range(10), 9)
         # determine the last digit to make it qualify the test
         digits.append(_checksum(digits))
         # repeat steps until it does qualify the test
diff --git a/faker/providers/ssn/hr_HR/__init__.py b/faker/providers/ssn/hr_HR/__init__.py
index f110a5e9..9eb73ed1 100644
--- a/faker/providers/ssn/hr_HR/__init__.py
+++ b/faker/providers/ssn/hr_HR/__init__.py
@@ -2,7 +2,6 @@
 
 from __future__ import unicode_literals
 from .. import Provider as SsnProvider
-from faker.generator import random
 
 
 def checksum(digits):
@@ -34,9 +33,8 @@ class Provider(SsnProvider):
     (international standard ISO 7064, module 11.10).
     """
 
-    @classmethod
-    def ssn(cls):
-        digits = random.sample(range(10), 10)
+    def ssn(self):
+        digits = self.generator.random.sample(range(10), 10)
 
         digits.append(checksum(digits))
 
diff --git a/faker/providers/ssn/hu_HU/__init__.py b/faker/providers/ssn/hu_HU/__init__.py
index ad7da421..8a421b34 100644
--- a/faker/providers/ssn/hu_HU/__init__.py
+++ b/faker/providers/ssn/hu_HU/__init__.py
@@ -1,6 +1,6 @@
 # coding=utf-8
 from __future__ import unicode_literals
-from .. import Provider as BaseProvider
+from .. import Provider as SsnProvider
 from functools import reduce
 from math import fmod
 
@@ -10,9 +10,8 @@ def zfix(d):
     else:
         return d
 
-class Provider(BaseProvider):
-    @classmethod
-    def ssn(cls, dob=None, gender=None):
+class Provider(SsnProvider):
+    def ssn(self, dob=None, gender=None):
         """
         Generates Hungarian SSN equivalent (személyazonosító szám or, colloquially, személyi szám)
 
@@ -67,11 +66,11 @@ class Provider(BaseProvider):
         #
 
         if dob:
-            E = dob[0:2]
-            H = dob[2:4]
-            N = dob[4:6]
+            E = int(dob[0:2])
+            H = int(dob[2:4])
+            N = int(dob[4:6])
 
-            if int(dob[0:2]) <= 17:
+            if E <= 17:
                 # => person born after '99 in all likelihood...
                 if gender:
                     if gender.upper() == "F":
@@ -81,7 +80,7 @@ class Provider(BaseProvider):
                     else:
                         raise ValueError("Unknown gender - specify M or F.")
                 else:
-                    M = BaseProvider.random_int(3, 4)
+                    M = self.generator.random_int(3, 4)
             else:
                 # => person born before '99.
                 if gender:
@@ -92,12 +91,12 @@ class Provider(BaseProvider):
                     else:
                         raise ValueError("Unknown gender - specify M or F.")
                 else:
-                    M = BaseProvider.random_int(1, 2)
+                    M = self.generator.random_int(1, 2)
         elif gender:
             # => assume statistically that the person will be born before '99.
-            E = BaseProvider.random_int(17, 99)
-            H = BaseProvider.random_int(1, 12)
-            N = BaseProvider.random_int(1, 30)
+            E = self.generator.random_int(17, 99)
+            H = self.generator.random_int(1, 12)
+            N = self.generator.random_int(1, 30)
 
             if gender.upper() == "F":
                 M = 2
@@ -106,14 +105,14 @@ class Provider(BaseProvider):
             else:
                 raise ValueError("Unknown gender - specify M or F")
         else:
-            M = BaseProvider.random_int(1, 2)
-            E = BaseProvider.random_int(17, 99)
-            H = BaseProvider.random_int(1, 12)
-            N = BaseProvider.random_int(1, 30)
+            M = self.generator.random_int(1, 2)
+            E = self.generator.random_int(17, 99)
+            H = self.generator.random_int(1, 12)
+            N = self.generator.random_int(1, 30)
 
         H = zfix(H)
         N = zfix(N)
-        S = "{}{}{}".format(BaseProvider.random_digit(), BaseProvider.random_digit(), BaseProvider.random_digit())
+        S = "{}{}{}".format(self.generator.random_digit(), self.generator.random_digit(), self.generator.random_digit())
 
         vdig = "{M}{E}{H}{N}{S}".format(M=M, E=E, H=H, N=N, S=S)
 
diff --git a/faker/providers/ssn/it_IT/__init__.py b/faker/providers/ssn/it_IT/__init__.py
index 6b95ecda..51df7e4b 100644
--- a/faker/providers/ssn/it_IT/__init__.py
+++ b/faker/providers/ssn/it_IT/__init__.py
@@ -31,7 +31,6 @@ class Provider(SsnProvider):
     '''
     fiscal_code_format = '??????##?##?###'
 
-    @classmethod
-    def ssn(cls):
-        code = cls.bothify(cls.fiscal_code_format).upper()
+    def ssn(self):
+        code = self.bothify(self.fiscal_code_format).upper()
         return code + checksum(code)
diff --git a/faker/providers/ssn/nl_BE/__init__.py b/faker/providers/ssn/nl_BE/__init__.py
index f79c41bc..8897c96d 100644
--- a/faker/providers/ssn/nl_BE/__init__.py
+++ b/faker/providers/ssn/nl_BE/__init__.py
@@ -2,9 +2,6 @@
 
 from __future__ import unicode_literals
 from .. import Provider as SsnProvider
-from faker.generator import random
-from faker.providers.date_time import Provider as DateProvider
-from faker.providers import BaseProvider
 
 """
 For more info on rijksregisternummer, see https://nl.wikipedia.org/wiki/Rijksregisternummer
@@ -13,8 +10,7 @@ Dutch/French only for now ...
 
 class Provider(SsnProvider):
 
-    @classmethod
-    def ssn(cls):
+    def ssn(self):
         """
         Returns a 11 digits Belgian SSN called "rijksregisternummer" as a string
 
@@ -26,15 +22,15 @@ class Provider(SsnProvider):
         Divide those 9 digits by 97, subtract the remainder from 97 and that's the result.
         For persons born in or after 2000, the 9 digit number needs to be proceeded by a 2
         (add 2000000000) before the division by 97.
-                
+
         """
         # see http://nl.wikipedia.org/wiki/Burgerservicenummer (in Dutch)
         def _checksum(digits):
             res = 97 - (digits % 97)
             return res
-        
+
         # Generate a date (random)
-        mydate = DateProvider.date()        
+        mydate = self.generator.date()
         # Convert it to an int
         elms = mydate.split("-")
         # Adjust for year 2000 if necessary
@@ -45,7 +41,7 @@ class Provider(SsnProvider):
         # Only keep the last 2 digits of the year
         elms[0] = elms[0][2:4]
         # Simulate the gender/sequence - should be 3 digits
-        seq = BaseProvider.random_int(1,998)
+        seq = self.generator.random_int(1,998)
         # Right justify sequence and append to list
         seq_str = "{:0>3}".format(seq)
         elms.append(seq_str)
@@ -58,4 +54,4 @@ class Provider(SsnProvider):
         s_rjust = "{:0>2}".format(s)
         # return result as a string
         elms.append(s_rjust)
-        return "".join(elms)
\ No newline at end of file
+        return "".join(elms)
diff --git a/faker/providers/ssn/nl_NL/__init__.py b/faker/providers/ssn/nl_NL/__init__.py
index 087a5509..2d3c1830 100644
--- a/faker/providers/ssn/nl_NL/__init__.py
+++ b/faker/providers/ssn/nl_NL/__init__.py
@@ -2,13 +2,11 @@
 
 from __future__ import unicode_literals
 from .. import Provider as SsnProvider
-from faker.generator import random
 
 
 class Provider(SsnProvider):
 
-    @classmethod
-    def ssn(cls):
+    def ssn(self):
         """
         Returns a 9 digits Dutch SSN called "burgerservicenummer (BSN)".
 
@@ -26,7 +24,7 @@ class Provider(SsnProvider):
 
         while True:
             # create an array of first 8 elements initialized randomly
-            digits = random.sample(range(10), 8)
+            digits = self.generator.random.sample(range(10), 8)
             # sum those 8 digits according to (part of) the "11-proef"
             s = _checksum(digits)
             # determine the last digit to make it qualify the test
diff --git a/faker/providers/ssn/pl_PL/__init__.py b/faker/providers/ssn/pl_PL/__init__.py
index 378519e9..275aa7f5 100644
--- a/faker/providers/ssn/pl_PL/__init__.py
+++ b/faker/providers/ssn/pl_PL/__init__.py
@@ -2,7 +2,6 @@
 
 from __future__ import unicode_literals
 from .. import Provider as SsnProvider
-from faker.providers.date_time import Provider as DateTimeProvider
 
 
 def checksum(digits):
@@ -32,8 +31,7 @@ def calculate_month(birth_date):
 
 class Provider(SsnProvider):
 
-    @classmethod
-    def ssn(cls):
+    def ssn(self):
         """
         Returns 11 character Polish national identity code (Public Electronic Census System,
         Polish: Powszechny Elektroniczny System Ewidencji Ludności - PESEL).
@@ -44,7 +42,7 @@ class Provider(SsnProvider):
 
         https://en.wikipedia.org/wiki/National_identification_number#Poland
         """
-        birth_date = DateTimeProvider.date_time()
+        birth_date = self.generator.date_time()
 
         year_without_century = int(birth_date.strftime('%y'))
         month = calculate_month(birth_date)
@@ -59,7 +57,7 @@ class Provider(SsnProvider):
         ]
 
         for _ in range(4):
-            pesel_digits.append(cls.random_digit())
+            pesel_digits.append(self.random_digit())
 
         pesel_digits.append(checksum(pesel_digits))
 
diff --git a/faker/providers/ssn/pt_BR/__init__.py b/faker/providers/ssn/pt_BR/__init__.py
index d039b4ab..7fcdcda1 100644
--- a/faker/providers/ssn/pt_BR/__init__.py
+++ b/faker/providers/ssn/pt_BR/__init__.py
@@ -2,7 +2,6 @@
 
 from __future__ import unicode_literals
 from .. import Provider as SsnProvider
-from faker.generator import random
 
 
 def checksum(digits):
@@ -27,9 +26,8 @@ class Provider(SsnProvider):
     The cpf return a valid number formatted with brazilian mask. eg nnn.nnn.nnn-nn
     """
 
-    @classmethod
-    def ssn(cls):
-        digits = random.sample(range(10), 9)
+    def ssn(self):
+        digits = self.generator.random.sample(range(10), 9)
 
         dv = checksum(digits)
         digits.append(dv)
@@ -37,7 +35,6 @@ class Provider(SsnProvider):
 
         return ''.join(map(str, digits))
 
-    @classmethod
-    def cpf(cls):
-        c = Provider.ssn()
+    def cpf(self):
+        c = self.ssn()
         return c[:3] + '.' + c[3:6] + '.' + c[6:9] + '-' + c[9:]
diff --git a/faker/providers/ssn/sv_SE/__init__.py b/faker/providers/ssn/sv_SE/__init__.py
index 78864548..0d3a2a6c 100644
--- a/faker/providers/ssn/sv_SE/__init__.py
+++ b/faker/providers/ssn/sv_SE/__init__.py
@@ -2,14 +2,12 @@
 
 from __future__ import unicode_literals
 from .. import Provider as SsnProvider
-from faker.generator import random
 import datetime
 
 
 class Provider(SsnProvider):
 
-    @classmethod
-    def ssn(cls):
+    def ssn(self):
         """
         Returns a 10 digit Swedish SSN, "Personnummer".
 
@@ -37,10 +35,10 @@ class Provider(SsnProvider):
 
         min_age = 18 * 365
         max_age = 90 * 365
-        age = datetime.timedelta(days=random.randrange(min_age, max_age))
+        age = datetime.timedelta(days=self.generator.random.randrange(min_age, max_age))
         birthday = datetime.datetime.now() - age
         pnr_date = birthday.strftime('%y%m%d')
-        suffix = str(random.randrange(0, 999)).zfill(3)
+        suffix = str(self.generator.random.randrange(0, 999)).zfill(3)
         luhn_checksum = str(_calculate_luhn(pnr_date + suffix))
         pnr = '{0}-{1}{2}'.format(pnr_date, suffix, luhn_checksum)
 
diff --git a/faker/providers/ssn/uk_UA/__init__.py b/faker/providers/ssn/uk_UA/__init__.py
index 9f26f773..d43b4bf3 100644
--- a/faker/providers/ssn/uk_UA/__init__.py
+++ b/faker/providers/ssn/uk_UA/__init__.py
@@ -4,12 +4,10 @@ from __future__ import unicode_literals
 from datetime import date
 
 from .. import Provider as SsnProvider
-from faker.providers.date_time import Provider as DateTimeProvider
 
 
 class Provider(SsnProvider):
-    @classmethod
-    def ssn(cls):
+    def ssn(self):
         """
         Ukrainian "Реєстраційний номер облікової картки платника податків"
         also known as "Ідентифікаційний номер фізичної особи".
@@ -17,13 +15,13 @@ class Provider(SsnProvider):
         digits = []
 
         # Number of days between 1899-12-31 and a birth date
-        for digit in str((DateTimeProvider.date_object() -
+        for digit in str((self.generator.date_object() -
                           date(1899, 12, 31)).days):
             digits.append(int(digit))
 
         # Person's sequence number
         for _ in range(4):
-            digits.append(cls.random_int(0, 9))
+            digits.append(self.random_int(0, 9))
 
         checksum = (digits[0]*-1 + digits[1]*5 + digits[2]*7 + digits[3]*9 +
                     digits[4]*4 + digits[5]*6 + digits[6]*10 + digits[7]*5 +
diff --git a/faker/providers/ssn/zh_CN/__init__.py b/faker/providers/ssn/zh_CN/__init__.py
index 7b4f0eb0..e785f475 100644
--- a/faker/providers/ssn/zh_CN/__init__.py
+++ b/faker/providers/ssn/zh_CN/__init__.py
@@ -358,16 +358,15 @@ class Provider(SsnProvider):
                   "654323", "654324", "654325", "654326", "659000", "659001", "659002", "659003", "659004", "710000",
                   "810000", "820000"]
 
-    @classmethod
-    def ssn(cls):
+    def ssn(self):
         def checksum(s):
             return str((1 - 2 * int(s, 13)) % 11).replace('10', 'X')
 
         min_age = 18 * 365
         max_age = 90 * 365
-        age = datetime.timedelta(days=cls.random_int(min_age, max_age))
+        age = datetime.timedelta(days=self.random_int(min_age, max_age))
         birthday = datetime.date.today() - age
         birthday_str = birthday.strftime('%Y%m%d')
 
-        ssn_without_checksum = cls.numerify(cls.random_element(cls.area_codes) + birthday_str + "###")
+        ssn_without_checksum = self.numerify(self.random_element(self.area_codes) + birthday_str + "###")
         return ssn_without_checksum + checksum(ssn_without_checksum)
diff --git a/faker/providers/ssn/zh_TW/__init__.py b/faker/providers/ssn/zh_TW/__init__.py
index 41837f01..3eec5bd6 100644
--- a/faker/providers/ssn/zh_TW/__init__.py
+++ b/faker/providers/ssn/zh_TW/__init__.py
@@ -6,6 +6,5 @@ from .. import Provider as SsnProvider
 class Provider(SsnProvider):
     ssn_formats = ("?#########",)
 
-    @classmethod
-    def ssn(cls):
-        return cls.bothify(cls.random_element(cls.ssn_formats)).upper()
+    def ssn(self):
+        return self.bothify(self.random_element(self.ssn_formats)).upper()
diff --git a/faker/providers/user_agent/__init__.py b/faker/providers/user_agent/__init__.py
index 55e18773..69fbb4bf 100644
--- a/faker/providers/user_agent/__init__.py
+++ b/faker/providers/user_agent/__init__.py
@@ -4,10 +4,6 @@ from __future__ import unicode_literals
 
 from datetime import datetime
 
-from faker.generator import random
-from faker.providers.date_time import Provider as DatetimeProvider
-from faker.providers.misc import Provider as MiscProvider
-
 from .. import BaseProvider
 
 
@@ -27,86 +23,80 @@ class Provider(BaseProvider):
 
     mac_processors = ('Intel', 'PPC', 'U; Intel', 'U; PPC',)
 
-    @classmethod
-    def mac_processor(cls):
-        return cls.random_element(cls.mac_processors)
+    def mac_processor(self):
+        return self.random_element(self.mac_processors)
 
-    @classmethod
-    def linux_processor(cls):
-        return cls.random_element(cls.linux_processors)
+    def linux_processor(self):
+        return self.random_element(self.linux_processors)
 
-    @classmethod
-    def user_agent(cls):
-        name = cls.random_element(cls.user_agents)
-        return getattr(cls, name)()
+    def user_agent(self):
+        name = self.random_element(self.user_agents)
+        return getattr(self, name)()
 
-    @classmethod
-    def chrome(cls):
-        saf = str(random.randint(531, 536)) + str(random.randint(0, 2))
+    def chrome(self):
+        saf = str(self.generator.random.randint(531, 536)) + str(self.generator.random.randint(0, 2))
         tmplt = '({0}) AppleWebKit/{1} (KHTML, like Gecko)' \
                 ' Chrome/{2}.0.{3}.0 Safari/{4}'
         platforms = (
-            tmplt.format(cls.linux_platform_token(),
+            tmplt.format(self.linux_platform_token(),
                          saf,
-                         random.randint(13, 15),
-                         random.randint(800, 899),
+                         self.generator.random.randint(13, 15),
+                         self.generator.random.randint(800, 899),
                          saf),
-            tmplt.format(cls.windows_platform_token(),
+            tmplt.format(self.windows_platform_token(),
                          saf,
-                         random.randint(13, 15),
-                         random.randint(800, 899),
+                         self.generator.random.randint(13, 15),
+                         self.generator.random.randint(800, 899),
                          saf),
-            tmplt.format(cls.mac_platform_token(),
+            tmplt.format(self.mac_platform_token(),
                          saf,
-                         random.randint(13, 15),
-                         random.randint(800, 899),
+                         self.generator.random.randint(13, 15),
+                         self.generator.random.randint(800, 899),
                          saf),
         )
 
-        return 'Mozilla/5.0 ' + cls.random_element(platforms)
+        return 'Mozilla/5.0 ' + self.random_element(platforms)
 
-    @classmethod
-    def firefox(cls):
+    def firefox(self):
         ver = (
             'Gecko/{0} Firefox/{1}.0'.format(
-                DatetimeProvider.date_time_between(
-                    datetime(2011, 1, 1)), random.randint(4, 15)),
+                self.generator.date_time_between(
+                    datetime(2011, 1, 1)), self.generator.random.randint(4, 15)),
             'Gecko/{0} Firefox/3.6.{1}'.format(
-                DatetimeProvider.date_time_between(
-                    datetime(2010, 1, 1)), random.randint(1, 20)),
+                self.generator.date_time_between(
+                    datetime(2010, 1, 1)), self.generator.random.randint(1, 20)),
             'Gecko/{0} Firefox/3.8'.format(
-                DatetimeProvider.date_time_between(
+                self.generator.date_time_between(
                     datetime(2010, 1, 1)), ),
         )
         tmplt_win = '({0}; {1}; rv:1.9.{2}.20) {3}'
         tmplt_lin = '({0}; rv:1.9.{1}.20) {2}'
         tmplt_mac = '({0}; rv:1.9.{1}.20) {2}'
         platforms = (
-            tmplt_win.format(cls.windows_platform_token(),
-                             MiscProvider.locale().replace('_', '-'),
-                             random.randint(0, 2),
-                             random.choice(ver)),
-            tmplt_lin.format(cls.linux_platform_token(),
-                             random.randint(5, 7),
-                             random.choice(ver)),
-            tmplt_mac.format(cls.mac_platform_token(),
-                             random.randint(2, 6),
-                             random.choice(ver)),
+            tmplt_win.format(self.windows_platform_token(),
+                             self.generator.locale().replace('_', '-'),
+                             self.generator.random.randint(0, 2),
+                             self.generator.random.choice(ver)),
+            tmplt_lin.format(self.linux_platform_token(),
+                             self.generator.random.randint(5, 7),
+                             self.generator.random.choice(ver)),
+            tmplt_mac.format(self.mac_platform_token(),
+                             self.generator.random.randint(2, 6),
+                             self.generator.random.choice(ver)),
         )
 
-        return 'Mozilla/5.0 ' + cls.random_element(platforms)
+        return 'Mozilla/5.0 ' + self.random_element(platforms)
 
-    @classmethod
-    def safari(cls):
-        saf = "{0}.{1}.{2}".format(random.randint(531, 535),
-                                   random.randint(1, 50),
-                                   random.randint(1, 7))
-        if not random.getrandbits(1):
-            ver = "{0}.{1}".format(random.randint(4, 5),
-                                   random.randint(0, 1))
+    def safari(self):
+        saf = "{0}.{1}.{2}".format(self.generator.random.randint(531, 535),
+                                   self.generator.random.randint(1, 50),
+                                   self.generator.random.randint(1, 7))
+        if not self.generator.random.getrandbits(1):
+            ver = "{0}.{1}".format(self.generator.random.randint(4, 5),
+                                   self.generator.random.randint(0, 1))
         else:
-            ver = "{0}.0.{1}".format(random.randint(4, 5),
-                                     random.randint(1, 5))
+            ver = "{0}.0.{1}".format(self.generator.random.randint(4, 5),
+                                     self.generator.random.randint(1, 5))
         tmplt_win = '(Windows; U; {0}) AppleWebKit/{1} (KHTML, like Gecko)' \
                     ' Version/{2} Safari/{3}'
         tmplt_mac = '({0} rv:{1}.0; {2}) AppleWebKit/{3} (KHTML, like Gecko)' \
@@ -114,65 +104,60 @@ class Provider(BaseProvider):
         tmplt_ipod = '(iPod; U; CPU iPhone OS {0}_{1} like Mac OS X; {2})' \
                      ' AppleWebKit/{3} (KHTML, like Gecko) Version/{4}.0.5' \
                      ' Mobile/8B{5} Safari/6{6}'
-        locale = MiscProvider.locale().replace('_', '-')
+        locale = self.generator.locale().replace('_', '-')
         platforms = (
-            tmplt_win.format(cls.windows_platform_token(),
+            tmplt_win.format(self.windows_platform_token(),
                              saf,
                              ver,
                              saf),
-            tmplt_mac.format(cls.mac_platform_token(),
-                             random.randint(2, 6),
+            tmplt_mac.format(self.mac_platform_token(),
+                             self.generator.random.randint(2, 6),
                              locale,
                              saf,
                              ver,
                              saf),
-            tmplt_ipod.format(random.randint(3, 4),
-                              random.randint(0, 3),
+            tmplt_ipod.format(self.generator.random.randint(3, 4),
+                              self.generator.random.randint(0, 3),
                               locale,
                               saf,
-                              random.randint(3, 4),
-                              random.randint(111, 119),
+                              self.generator.random.randint(3, 4),
+                              self.generator.random.randint(111, 119),
                               saf),
         )
 
-        return 'Mozilla/5.0 ' + cls.random_element(platforms)
+        return 'Mozilla/5.0 ' + self.random_element(platforms)
 
-    @classmethod
-    def opera(cls):
+    def opera(self):
         platform = '({0}; {1}) Presto/2.9.{2} Version/{3}.00'.format(
             (
-                cls.linux_platform_token() if random.getrandbits(1)
-                else cls.windows_platform_token()
+                self.linux_platform_token() if self.generator.random.getrandbits(1)
+                else self.windows_platform_token()
             ),
-            MiscProvider.locale().replace('_', '-'),
-            random.randint(160, 190),
-            random.randint(10, 12),
+            self.generator.locale().replace('_', '-'),
+            self.generator.random.randint(160, 190),
+            self.generator.random.randint(10, 12),
         )
         return 'Opera/{0}.{1}.{2}'.format(
-            random.randint(8, 9),
-            random.randint(10, 99),
+            self.generator.random.randint(8, 9),
+            self.generator.random.randint(10, 99),
             platform,
         )
 
-    @classmethod
-    def internet_explorer(cls):
+    def internet_explorer(self):
         tmplt = 'Mozilla/5.0 (compatible; MSIE {0}.0; {1}; Trident/{2}.{3})'
-        return tmplt.format(random.randint(5, 9),
-                            cls.windows_platform_token(),
-                            random.randint(3, 5),
-                            random.randint(0, 1))
+        return tmplt.format(self.generator.random.randint(5, 9),
+                            self.windows_platform_token(),
+                            self.generator.random.randint(3, 5),
+                            self.generator.random.randint(0, 1))
 
-    @classmethod
-    def windows_platform_token(cls):
-        return cls.random_element(cls.windows_platform_tokens)
+    def windows_platform_token(self):
+        return self.random_element(self.windows_platform_tokens)
 
-    @classmethod
-    def linux_platform_token(cls):
+    def linux_platform_token(self):
         return 'X11; Linux {0}'.format(
-            cls.random_element(cls.linux_processors))
+            self.random_element(self.linux_processors))
 
-    @classmethod
-    def mac_platform_token(cls):
+    def mac_platform_token(self):
         return 'Macintosh; {0} Mac OS X 10_{1}_{2}'.format(
-            cls.random_element(cls.mac_processors),
-            random.randint(5, 8), random.randint(0, 9))
+            self.random_element(self.mac_processors),
+            self.generator.random.randint(5, 8), self.generator.random.randint(0, 9))
diff --git a/faker/utils/distribution.py b/faker/utils/distribution.py
index 46a8a8ed..6957988a 100644
--- a/faker/utils/distribution.py
+++ b/faker/utils/distribution.py
@@ -1,9 +1,11 @@
 # coding=utf-8
 
 import bisect
-from faker.generator import random
+from faker.generator import mod_random
 
-def random_sample():
+def random_sample(random=None):
+    if random is None:
+        random = mod_random
     return random.uniform(0.0, 1.0)
 
 
@@ -14,7 +16,10 @@ def cumsum(it):
         yield total
 
 
-def choice_distribution(a, p):
+def choice_distribution(a, p, random=None):
+    if random is None:
+        random = mod_random
+
     assert len(a) == len(p)
 
     if hasattr(random, 'choices'):
@@ -23,6 +28,6 @@ def choice_distribution(a, p):
         cdf = list(cumsum(p))
         normal = cdf[-1]
         cdf2 = [float(i) / float(normal) for i in cdf]
-        uniform_sample = random_sample()
+        uniform_sample = random_sample(random=random)
         idx = bisect.bisect_right(cdf2, uniform_sample)
         return a[idx]


Test patch:
diff --git a/tests/factory.py b/tests/factory.py
index 62ae0377..f2a09113 100644
--- a/tests/factory.py
+++ b/tests/factory.py
@@ -14,7 +14,7 @@ except ImportError:  # pragma: no cover
     from io import StringIO
 
 from faker import Generator, Factory
-from faker.generator import random
+from faker.generator import mod_random as random
 from faker.utils import text, decorators
 from . import string_types
 
@@ -165,7 +165,7 @@ class FactoryTestCase(unittest.TestCase):
 
     def test_random_element(self):
         from faker.providers import BaseProvider
-        provider = BaseProvider(None)
+        provider = BaseProvider(self.generator)
 
         choices = ('a', 'b', 'c', 'd')
         pick = provider.random_element(choices)
@@ -181,45 +181,49 @@ class FactoryTestCase(unittest.TestCase):
 
     def test_binary(self):
         from faker.providers.misc import Provider
+        provider = Provider(self.generator)
 
         for _ in range(999):
             length = random.randint(0, 2 ** 10)
-            binary = Provider.binary(length)
+            binary = provider.binary(length)
 
             self.assertTrue(isinstance(binary, (bytes, bytearray)))
             self.assertTrue(len(binary) == length)
 
         for _ in range(999):
             self.generator.seed(_)
-            binary1 = Provider.binary(_)
+            binary1 = provider.binary(_)
             self.generator.seed(_)
-            binary2 = Provider.binary(_)
+            binary2 = provider.binary(_)
 
             self.assertTrue(binary1 == binary2)
 
     def test_language_code(self):
         from faker.providers.misc import Provider
+        provider = Provider(self.generator)
 
         for _ in range(99):
-            language_code = Provider.language_code()
+            language_code = provider.language_code()
             self.assertTrue(isinstance(language_code, string_types))
             self.assertTrue(re.match(r'^[a-z]{2,3}$', language_code))
 
     def test_locale(self):
         from faker.providers.misc import Provider
+        provider = Provider(self.generator)
 
         for _ in range(99):
-            locale = Provider.locale()
+            locale = provider.locale()
             self.assertTrue(re.match(r'^[a-z]{2,3}_[A-Z]{2}$', locale))
 
     def test_password(self):
         from faker.providers.misc import Provider
+        provider = Provider(self.generator)
 
         def in_string(char, _str):
             return char in _str
 
         for _ in range(999):
-            password = Provider.password()
+            password = provider.password()
 
             self.assertTrue(any([in_string(char, password) for char in "!@#$%^&*()_+"]))
             self.assertTrue(any([in_string(char, password) for char in string.digits]))
@@ -227,7 +231,7 @@ class FactoryTestCase(unittest.TestCase):
             self.assertTrue(any([in_string(char, password) for char in string.ascii_lowercase]))
 
         with self.assertRaises(AssertionError):
-            Provider.password(length=2)
+            provider.password(length=2)
 
     def test_prefix_suffix_always_string(self):
         # Locales known to contain `*_male` and `*_female`.
@@ -240,7 +244,7 @@ class FactoryTestCase(unittest.TestCase):
     def test_no_words_sentence(self):
         from faker.providers.lorem import Provider
 
-        provider = Provider(None)
+        provider = Provider(self.generator)
 
         paragraph = provider.paragraph(0)
         self.assertEqual(paragraph, '')
@@ -252,7 +256,7 @@ class FactoryTestCase(unittest.TestCase):
     def test_no_words_paragraph(self):
         from faker.providers.lorem import Provider
 
-        provider = Provider(None)
+        provider = Provider(self.generator)
 
         sentence = provider.sentence(0)
         self.assertEqual(sentence, '')
@@ -276,7 +280,7 @@ class FactoryTestCase(unittest.TestCase):
 
     def test_random_pystr_characters(self):
         from faker.providers.python import Provider
-        provider = Provider(None)
+        provider = Provider(self.generator)
 
         characters = provider.pystr()
         self.assertEqual(len(characters), 20)
@@ -291,7 +295,7 @@ class FactoryTestCase(unittest.TestCase):
 
     def test_random_pyfloat(self):
         from faker.providers.python import Provider
-        provider = Provider(None)
+        provider = Provider(self.generator)
 
         self.assertTrue(0 <= abs(provider.pyfloat(left_digits=1)) < 10)
         self.assertTrue(0 <= abs(provider.pyfloat(left_digits=0)) < 1)
@@ -305,7 +309,7 @@ class FactoryTestCase(unittest.TestCase):
     def test_us_ssn_valid(self):
         from faker.providers.ssn.en_US import Provider
 
-        provider = Provider(None)
+        provider = Provider(self.generator)
         for i in range(1000):
             ssn = provider.ssn()
             self.assertEqual(len(ssn), 11)
@@ -316,9 +320,8 @@ class FactoryTestCase(unittest.TestCase):
             self.assertNotEqual(ssn[7:11], '0000')
 
     def test_nl_BE_ssn_valid(self):
-        from faker.providers.ssn.nl_BE import Provider
-
-        provider = Provider(None)
+        import faker
+        provider = faker.Faker('nl_BE').provider('faker.providers.ssn')
 
         for i in range (1000):
             ssn = provider.ssn()
@@ -354,7 +357,7 @@ class FactoryTestCase(unittest.TestCase):
     def test_ipv4(self):
         from faker.providers.internet import Provider
 
-        provider = Provider(None)
+        provider = Provider(self.generator)
 
         for _ in range(999):
             address = provider.ipv4()
@@ -373,7 +376,7 @@ class FactoryTestCase(unittest.TestCase):
     def test_ipv6(self):
         from faker.providers.internet import Provider
 
-        provider = Provider(None)
+        provider = Provider(self.generator)
 
         for _ in range(999):
             address = provider.ipv6()
@@ -392,7 +395,7 @@ class FactoryTestCase(unittest.TestCase):
 
     def test_random_sample_unique(self):
         from faker.providers import BaseProvider
-        provider = BaseProvider(None)
+        provider = BaseProvider(self.generator)
 
         sample = provider.random_sample_unique('abcde', 3)
         self.assertEqual(len(sample), 3)
@@ -417,7 +420,7 @@ class FactoryTestCase(unittest.TestCase):
 
     def test_random_number(self):
         from faker.providers import BaseProvider
-        provider = BaseProvider
+        provider = BaseProvider(self.generator)
 
         number = provider.random_number(10, True)
         self.assertEqual(len(str(number)), 10)
diff --git a/tests/providers/__init__.py b/tests/providers/__init__.py
index e69de29b..9a687f87 100644
--- a/tests/providers/__init__.py
+++ b/tests/providers/__init__.py
@@ -0,0 +1,51 @@
+import unittest
+from faker import Factory
+from faker.providers import BaseProvider
+
+
+class BaseProviderTestCase(unittest.TestCase):
+    def setUp(self):
+        self.factory = Factory.create('en_US')
+        self.factory.seed(0)
+        self.provider = BaseProvider(generator=self.factory)
+
+    def test_random_digit_or_empty(self):
+        ret = self.provider.random_digit_or_empty()
+        assert isinstance(ret, int)
+        assert ret >= 0 and ret <= 9
+
+        self.factory.seed(1)
+        assert self.provider.random_digit_or_empty() == ''
+
+    def test_random_digit_not_null_or_empty(self):
+        ret = self.provider.random_digit_not_null_or_empty()
+        assert isinstance(ret, int)
+        assert ret >= 0 and ret <= 9
+
+        self.factory.seed(1)
+        assert self.provider.random_digit_not_null_or_empty() == ''
+
+    def test_randomize_nb_elements(self):
+        assert self.provider.randomize_nb_elements(number=1, le=True, ge=True) == 1
+
+        assert self.provider.randomize_nb_elements(le=True, ge=True) == 10
+
+        number = 9999
+        random_times = 100
+        lower_bound = int(number * 0.6)
+        upper_bound = int(number * 1.4)
+
+        for _ in range(random_times):
+            res = self.provider.randomize_nb_elements(number=number, le=True)
+            assert res >= lower_bound
+            assert res <= number
+
+        for _ in range(random_times):
+            res = self.provider.randomize_nb_elements(number=number, ge=True)
+            assert res >= number
+            assert res <= upper_bound
+
+        for _ in range(random_times):
+            res = self.provider.randomize_nb_elements(number=number)
+            assert res >= lower_bound
+            assert res <= upper_bound
diff --git a/tests/providers/address.py b/tests/providers/address.py
index b1fcec32..eca408f3 100644
--- a/tests/providers/address.py
+++ b/tests/providers/address.py
@@ -68,7 +68,7 @@ class TestHuHU(unittest.TestCase):
         # Hungarian postcodes begin with 'H-' followed by 4 digits.
         # The first digit may not begin with a zero.
         for _ in range(100):
-            pcd = HuProvider.postcode()
+            pcd = self.factory.postcode()
             assert pcd[2] > "0"
 
     def test_street_address(self):
diff --git a/tests/providers/color.py b/tests/providers/color.py
index ab6cf22d..73ab79f9 100644
--- a/tests/providers/color.py
+++ b/tests/providers/color.py
@@ -1,16 +1,20 @@
 import unittest
 from re import search
-from faker.providers.color.en_US import Provider as en_provider
+from faker import Factory
 
 
 class TestColor(unittest.TestCase):
+
+    def setUp(self):
+        self.factory = Factory.create('en_US')
+
     def test_safe_hex_color(self):
-        assert all((search(r'^#(?:[0-9a-fA-F]{3}){1,2}$', en_provider.safe_hex_color())
+        assert all((search(r'^#(?:[0-9a-fA-F]{3}){1,2}$', self.factory.safe_hex_color())
             for _ in range(1000)))
 
 
     def test_hex_color(self):
-        assert all((search(r'^#(?:[0-9a-fA-F]{3}){1,2}$', en_provider.hex_color())
+        assert all((search(r'^#(?:[0-9a-fA-F]{3}){1,2}$', self.factory.hex_color())
             for _ in range(1000)))
 
 
@@ -19,11 +23,11 @@ class TestColor(unittest.TestCase):
         minval = 0
 
         for _ in range(1000):
-            current = list(map(int, en_provider.rgb_color().split(',')))
+            current = list(map(int, self.factory.rgb_color().split(',')))
             if max(current) > maxval:
                 maxval = max(current)
             if min(current) > minval:
-                minval = min(current) 
+                minval = min(current)
 
         assert maxval <= 255
         assert minval >= 0
@@ -34,11 +38,11 @@ class TestColor(unittest.TestCase):
         minval = 0
 
         for _ in range(1000):
-            current = list(map(int, en_provider.rgb_css_color()[4:-1].split(',')))
+            current = list(map(int, self.factory.rgb_css_color()[4:-1].split(',')))
             if max(current) > maxval:
                 maxval = max(current)
             if min(current) > minval:
-                minval = min(current) 
+                minval = min(current)
 
         assert maxval <= 255
         assert minval >= 0
diff --git a/tests/providers/company.py b/tests/providers/company.py
index 06450c0a..126e7a03 100644
--- a/tests/providers/company.py
+++ b/tests/providers/company.py
@@ -45,11 +45,11 @@ class TestPtBR(unittest.TestCase):
 
     def test_pt_BR_company_id(self):
         for _ in range(100):
-            self.assertTrue(re.search(r'^\d{14}$', PtProvider.company_id()))
+            self.assertTrue(re.search(r'^\d{14}$', self.factory.company_id()))
 
     def test_pt_BR_cnpj(self):
         for _ in range(100):
-            cnpj = PtProvider.cnpj()
+            cnpj = self.factory.cnpj()
             self.assertTrue(re.search(r'\d{2}\.\d{3}\.\d{3}/0001-\d{2}', cnpj))
 
 
@@ -85,7 +85,7 @@ class TestPlPL(unittest.TestCase):
 
     def test_regon(self):
         for _ in range(100):
-            self.assertTrue(re.search(r'^\d{9}$', PlProvider.regon()))
+            self.assertTrue(re.search(r'^\d{9}$', self.factory.regon()))
 
     def test_local_regon_checksum(self):
         self.assertEqual(local_regon_checksum([1, 2, 3, 4, 5, 6, 7, 8, 5, 1, 2, 3, 4]), 7)
@@ -96,7 +96,7 @@ class TestPlPL(unittest.TestCase):
 
     def test_local_regon(self):
         for _ in range(100):
-            self.assertTrue(re.search(r'^\d{14}$', PlProvider.local_regon()))
+            self.assertTrue(re.search(r'^\d{14}$', self.factory.local_regon()))
 
     def test_company_vat_checksum(self):
         self.assertEqual(company_vat_checksum([7, 7, 5, 7, 7, 7, 6, 0, 5]), 9)
@@ -107,4 +107,4 @@ class TestPlPL(unittest.TestCase):
 
     def test_company_vat(self):
         for _ in range(100):
-            self.assertTrue(re.search(r'^\d{10}$', PlProvider.company_vat()))
+            self.assertTrue(re.search(r'^\d{10}$', self.factory.company_vat()))
diff --git a/tests/providers/date_time.py b/tests/providers/date_time.py
index 5c184bbd..b63551c4 100644
--- a/tests/providers/date_time.py
+++ b/tests/providers/date_time.py
@@ -5,11 +5,11 @@ from datetime import date, datetime, timedelta, tzinfo
 from datetime import time as datetime_time
 import time
 import unittest
+import random
 
 from faker import Factory
-from faker.generator import random
 from faker.providers.date_time import Provider as DatetimeProvider
-from faker.providers.date_time.ko_KR import Provider as koKRProvider
+from faker.providers.date_time.pl_PL import Provider as PlProvider
 from .. import string_types
 
 
@@ -117,59 +117,44 @@ class TestDateTime(unittest.TestCase):
         self.assertEqual(result, date(1850, 8, 2))
 
     def test_datetimes_with_and_without_tzinfo(self):
-        from faker.providers.date_time import Provider
-        provider = Provider
-
-        self.assertEqual(provider.date_time().tzinfo, None)
-        self.assertEqual(provider.date_time(utc).tzinfo, utc)
+        self.assertEqual(self.factory.date_time().tzinfo, None)
+        self.assertEqual(self.factory.date_time(utc).tzinfo, utc)
 
-        self.assertEqual(provider.date_time_ad().tzinfo, None)
-        self.assertEqual(provider.date_time_ad(utc).tzinfo, utc)
+        self.assertEqual(self.factory.date_time_ad().tzinfo, None)
+        self.assertEqual(self.factory.date_time_ad(utc).tzinfo, utc)
 
-        self.assertFalse(provider.iso8601().endswith('+00:00'))
-        self.assertTrue(provider.iso8601(utc).endswith('+00:00'))
+        self.assertFalse(self.factory.iso8601().endswith('+00:00'))
+        self.assertTrue(self.factory.iso8601(utc).endswith('+00:00'))
 
     def test_date_object(self):
-        from faker.providers.date_time import Provider
-        provider = Provider
-
-        self.assertIsInstance(provider.date_object(), date)
+        self.assertIsInstance(self.factory.date_object(), date)
 
     def test_time_object(self):
-        from faker.providers.date_time import Provider
-        provider = Provider
-
-        self.assertIsInstance(provider.time_object(), datetime_time)
+        self.assertIsInstance(self.factory.time_object(), datetime_time)
 
     def test_date_time_between_dates(self):
-        from faker.providers.date_time import Provider
-        provider = Provider
-
         timestamp_start = random.randint(0, 2000000000)
         timestamp_end = timestamp_start + 1
 
         datetime_start = datetime.fromtimestamp(timestamp_start)
         datetime_end = datetime.fromtimestamp(timestamp_end)
 
-        random_date = provider.date_time_between_dates(datetime_start, datetime_end)
+        random_date = self.factory.date_time_between_dates(datetime_start, datetime_end)
         self.assertTrue(datetime_start <= random_date)
         self.assertTrue(datetime_end >= random_date)
 
     def test_date_time_between_dates_with_tzinfo(self):
-        from faker.providers.date_time import Provider
-        provider = Provider
-
         timestamp_start = random.randint(0, 2000000000)
         timestamp_end = timestamp_start + 1
 
         datetime_start = datetime.fromtimestamp(timestamp_start, utc)
         datetime_end = datetime.fromtimestamp(timestamp_end, utc)
 
-        random_date_naive = provider.date_time_between_dates(datetime_start, datetime_end)
+        random_date_naive = self.factory.date_time_between_dates(datetime_start, datetime_end)
         with self.assertRaises(TypeError):
             datetime_start <= random_date_naive
 
-        random_date = provider.date_time_between_dates(datetime_start, datetime_end, utc)
+        random_date = self.factory.date_time_between_dates(datetime_start, datetime_end, utc)
         self.assertTrue(datetime_start <= random_date)
         self.assertTrue(datetime_end >= random_date)
 
@@ -177,70 +162,65 @@ class TestDateTime(unittest.TestCase):
         return int(time.mktime(value.timetuple()))
 
     def test_date_time_this_period(self):
-        from faker.providers.date_time import Provider
-        provider = Provider
         # test century
-        self.assertTrue(self._datetime_to_time(provider.date_time_this_century(after_now=False)) <= self._datetime_to_time(datetime.now()))
-        self.assertTrue(self._datetime_to_time(provider.date_time_this_century(before_now=False, after_now=True)) >= self._datetime_to_time(datetime.now()))
+        self.assertTrue(self._datetime_to_time(self.factory.date_time_this_century(after_now=False)) <= self._datetime_to_time(datetime.now()))
+        self.assertTrue(self._datetime_to_time(self.factory.date_time_this_century(before_now=False, after_now=True)) >= self._datetime_to_time(datetime.now()))
         # test decade
-        self.assertTrue(self._datetime_to_time(provider.date_time_this_decade(after_now=False)) <= self._datetime_to_time(datetime.now()))
-        self.assertTrue(self._datetime_to_time(provider.date_time_this_decade(before_now=False, after_now=True)) >= self._datetime_to_time(datetime.now()))
+        self.assertTrue(self._datetime_to_time(self.factory.date_time_this_decade(after_now=False)) <= self._datetime_to_time(datetime.now()))
+        self.assertTrue(self._datetime_to_time(self.factory.date_time_this_decade(before_now=False, after_now=True)) >= self._datetime_to_time(datetime.now()))
         self.assertEqual(
-            self._datetime_to_time(provider.date_time_this_decade(before_now=False, after_now=False)),
+            self._datetime_to_time(self.factory.date_time_this_decade(before_now=False, after_now=False)),
             self._datetime_to_time(datetime.now())
         )
         # test year
-        self.assertTrue(self._datetime_to_time(provider.date_time_this_year(after_now=False)) <= self._datetime_to_time(datetime.now()))
-        self.assertTrue(self._datetime_to_time(provider.date_time_this_year(before_now=False, after_now=True)) >= self._datetime_to_time(datetime.now()))
+        self.assertTrue(self._datetime_to_time(self.factory.date_time_this_year(after_now=False)) <= self._datetime_to_time(datetime.now()))
+        self.assertTrue(self._datetime_to_time(self.factory.date_time_this_year(before_now=False, after_now=True)) >= self._datetime_to_time(datetime.now()))
         self.assertEqual(
-            self._datetime_to_time(provider.date_time_this_year(before_now=False, after_now=False)),
+            self._datetime_to_time(self.factory.date_time_this_year(before_now=False, after_now=False)),
             self._datetime_to_time(datetime.now())
         )
         # test month
-        self.assertTrue(self._datetime_to_time(provider.date_time_this_month(after_now=False)) <= self._datetime_to_time(datetime.now()))
-        self.assertTrue(self._datetime_to_time(provider.date_time_this_month(before_now=False, after_now=True)) >= self._datetime_to_time(datetime.now()))
+        self.assertTrue(self._datetime_to_time(self.factory.date_time_this_month(after_now=False)) <= self._datetime_to_time(datetime.now()))
+        self.assertTrue(self._datetime_to_time(self.factory.date_time_this_month(before_now=False, after_now=True)) >= self._datetime_to_time(datetime.now()))
         self.assertEqual(
-            self._datetime_to_time(provider.date_time_this_month(before_now=False, after_now=False)),
+            self._datetime_to_time(self.factory.date_time_this_month(before_now=False, after_now=False)),
             self._datetime_to_time(datetime.now())
         )
 
     def test_date_time_this_period_with_tzinfo(self):
-        from faker.providers.date_time import Provider
-        provider = Provider
-
         # ensure all methods provide timezone aware datetimes
         with self.assertRaises(TypeError):
-            provider.date_time_this_century(before_now=False, after_now=True, tzinfo=utc) >= datetime.now()
+            self.factory.date_time_this_century(before_now=False, after_now=True, tzinfo=utc) >= datetime.now()
         with self.assertRaises(TypeError):
-            provider.date_time_this_decade(after_now=False, tzinfo=utc) <= datetime.now()
+            self.factory.date_time_this_decade(after_now=False, tzinfo=utc) <= datetime.now()
         with self.assertRaises(TypeError):
-            provider.date_time_this_year(after_now=False, tzinfo=utc) <= datetime.now()
+            self.factory.date_time_this_year(after_now=False, tzinfo=utc) <= datetime.now()
         with self.assertRaises(TypeError):
-            provider.date_time_this_month(after_now=False, tzinfo=utc) <= datetime.now()
+            self.factory.date_time_this_month(after_now=False, tzinfo=utc) <= datetime.now()
 
         # test century
-        self.assertTrue(provider.date_time_this_century(after_now=False, tzinfo=utc) <= datetime.now(utc))
-        self.assertTrue(provider.date_time_this_century(before_now=False, after_now=True, tzinfo=utc) >= datetime.now(utc))
+        self.assertTrue(self.factory.date_time_this_century(after_now=False, tzinfo=utc) <= datetime.now(utc))
+        self.assertTrue(self.factory.date_time_this_century(before_now=False, after_now=True, tzinfo=utc) >= datetime.now(utc))
         # test decade
-        self.assertTrue(provider.date_time_this_decade(after_now=False, tzinfo=utc) <= datetime.now(utc))
-        self.assertTrue(provider.date_time_this_decade(before_now=False, after_now=True, tzinfo=utc) >= datetime.now(utc))
+        self.assertTrue(self.factory.date_time_this_decade(after_now=False, tzinfo=utc) <= datetime.now(utc))
+        self.assertTrue(self.factory.date_time_this_decade(before_now=False, after_now=True, tzinfo=utc) >= datetime.now(utc))
 
         self.assertEqual(
-            provider.date_time_this_decade(before_now=False, after_now=False, tzinfo=utc).replace(second=0, microsecond=0),
+            self.factory.date_time_this_decade(before_now=False, after_now=False, tzinfo=utc).replace(second=0, microsecond=0),
             datetime.now(utc).replace(second=0, microsecond=0)
         )
         # test year
-        self.assertTrue(provider.date_time_this_year(after_now=False, tzinfo=utc) <= datetime.now(utc))
-        self.assertTrue(provider.date_time_this_year(before_now=False, after_now=True, tzinfo=utc) >= datetime.now(utc))
+        self.assertTrue(self.factory.date_time_this_year(after_now=False, tzinfo=utc) <= datetime.now(utc))
+        self.assertTrue(self.factory.date_time_this_year(before_now=False, after_now=True, tzinfo=utc) >= datetime.now(utc))
         self.assertEqual(
-            provider.date_time_this_year(before_now=False, after_now=False, tzinfo=utc).replace(second=0, microsecond=0),
+            self.factory.date_time_this_year(before_now=False, after_now=False, tzinfo=utc).replace(second=0, microsecond=0),
             datetime.now(utc).replace(second=0, microsecond=0)
         )
         # test month
-        self.assertTrue(provider.date_time_this_month(after_now=False, tzinfo=utc) <= datetime.now(utc))
-        self.assertTrue(provider.date_time_this_month(before_now=False, after_now=True, tzinfo=utc) >= datetime.now(utc))
+        self.assertTrue(self.factory.date_time_this_month(after_now=False, tzinfo=utc) <= datetime.now(utc))
+        self.assertTrue(self.factory.date_time_this_month(before_now=False, after_now=True, tzinfo=utc) >= datetime.now(utc))
         self.assertEqual(
-            provider.date_time_this_month(before_now=False, after_now=False, tzinfo=utc).replace(second=0, microsecond=0),
+            self.factory.date_time_this_month(before_now=False, after_now=False, tzinfo=utc).replace(second=0, microsecond=0),
             datetime.now(utc).replace(second=0, microsecond=0)
         )
 
@@ -261,31 +241,29 @@ class TestDateTime(unittest.TestCase):
             Provider._parse_timedelta('foobar')
 
     def test_time_series(self):
-        from faker.providers.date_time import Provider
-
-        series = [i for i in Provider.time_series()]
+        series = [i for i in self.factory.time_series()]
         self.assertTrue(len(series), 30)
         self.assertTrue(series[1][0] - series[0][0], timedelta(days=1))
 
         uniform = lambda dt: random.uniform(0, 5)  # noqa
-        series = [i for i in Provider.time_series('now', '+1w', '+1d', uniform)]
+        series = [i for i in self.factory.time_series('now', '+1w', '+1d', uniform)]
         self.assertTrue(len(series), 7)
         self.assertTrue(series[1][0] - series[0][0], timedelta(days=1))
 
         end = datetime.now() + timedelta(days=7)
-        series = [i for i in Provider.time_series('now', end, '+1d', uniform)]
+        series = [i for i in self.factory.time_series('now', end, '+1d', uniform)]
         self.assertTrue(len(series), 7)
         self.assertTrue(series[1][0] - series[0][0], timedelta(days=1))
 
         self.assertTrue(series[-1][0] <= end)
 
         with self.assertRaises(ValueError):
-            [i for i in Provider.time_series('+1w', 'now', '+1d', uniform)]
+            [i for i in self.factory.time_series('+1w', 'now', '+1d', uniform)]
 
         with self.assertRaises(ValueError):
-            [i for i in Provider.time_series('now', '+1w', '+1d', 'uniform')]
+            [i for i in self.factory.time_series('now', '+1w', '+1d', 'uniform')]
 
-        series = [i for i in Provider.time_series('now', end, '+1d', uniform, tzinfo=utc)]
+        series = [i for i in self.factory.time_series('now', end, '+1d', uniform, tzinfo=utc)]
         self.assertTrue(len(series), 7)
         self.assertTrue(series[1][0] - series[0][0], timedelta(days=1))
 
@@ -298,8 +276,8 @@ class TestPlPL(unittest.TestCase):
 
     def test_day(self):
         day = self.factory.day_of_week()
-        assert day in self.provider.DAY_NAMES.values()
+        assert day in PlProvider.DAY_NAMES.values()
 
     def test_month(self):
         month = self.factory.month_name()
-        assert month in self.provider.MONTH_NAMES.values()
+        assert month in PlProvider.MONTH_NAMES.values()
diff --git a/tests/providers/file.py b/tests/providers/file.py
index 1a1617ba..c9febf35 100644
--- a/tests/providers/file.py
+++ b/tests/providers/file.py
@@ -15,11 +15,11 @@ class TestFile(unittest.TestCase):
 
     def test_file_path(self):
         for _ in range(100):
-            file_path = FileProvider.file_path()
+            file_path = self.factory.file_path()
             self.assertTrue(re.search(r'\/\w+\/\w+\.\w+', file_path))
-            file_path = FileProvider.file_path(depth=3)
+            file_path = self.factory.file_path(depth=3)
             self.assertTrue(re.search(r'\/\w+\/\w+\/\w+\.\w+', file_path))
-            file_path = FileProvider.file_path(extension='pdf')
+            file_path = self.factory.file_path(extension='pdf')
             self.assertTrue(re.search(r'\/\w+\/\w+\.pdf', file_path))
-            file_path = FileProvider.file_path(category='image')
+            file_path = self.factory.file_path(category='image')
             self.assertTrue(re.search(r'\/\w+\/\w+\.(bmp|gif|jpeg|jpg|png|tiff)', file_path))
diff --git a/tests/providers/person.py b/tests/providers/person.py
index 925fd3e7..3bd070e6 100644
--- a/tests/providers/person.py
+++ b/tests/providers/person.py
@@ -119,4 +119,4 @@ class TestPlPL(unittest.TestCase):
 
     def test_identity_card_number(self):
         for _ in range(100):
-            self.assertTrue(re.search(r'^[A-Z]{3}\d{6}$', PlProvider.identity_card_number()))
+            self.assertTrue(re.search(r'^[A-Z]{3}\d{6}$', self.factory.identity_card_number()))
diff --git a/tests/providers/ssn.py b/tests/providers/ssn.py
index f4e5ad16..a176b3be 100644
--- a/tests/providers/ssn.py
+++ b/tests/providers/ssn.py
@@ -7,11 +7,10 @@ import re
 from datetime import datetime
 
 from faker import Factory
-from faker.providers.ssn.et_EE import Provider as EtProvider, checksum as et_checksum
-from faker.providers.ssn.hr_HR import Provider as HrProvider, checksum as hr_checksum
-from faker.providers.ssn.pt_BR import Provider as PtProvider, checksum as pt_checksum
-from faker.providers.ssn.pl_PL import (Provider as PlProvider, checksum as pl_checksum,
-                                       calculate_month as pl_calculate_mouth)
+from faker.providers.ssn.et_EE import checksum as et_checksum
+from faker.providers.ssn.hr_HR import checksum as hr_checksum
+from faker.providers.ssn.pt_BR import checksum as pt_checksum
+from faker.providers.ssn.pl_PL import checksum as pl_checksum, calculate_month as pl_calculate_mouth
 
 
 class TestEtEE(unittest.TestCase):
@@ -28,7 +27,7 @@ class TestEtEE(unittest.TestCase):
 
     def test_ssn(self):
         for _ in range(100):
-            self.assertTrue(re.search(r'^\d{11}$', EtProvider.ssn()))
+            self.assertTrue(re.search(r'^\d{11}$', self.factory.ssn()))
 
 
 class TestHrHR(unittest.TestCase):
@@ -47,7 +46,35 @@ class TestHrHR(unittest.TestCase):
 
     def test_ssn(self):
         for _ in range(100):
-            self.assertTrue(re.search(r'^\d{11}$', HrProvider.ssn()))
+            self.assertTrue(re.search(r'^\d{11}$', self.factory.ssn()))
+
+
+class TestHuHU(unittest.TestCase):
+    def setUp(self):
+        self.factory = Factory.create('hu_HU')
+        self.factory.seed(0)
+
+    def test_ssn(self):
+        for _ in range(100):
+            ssn = self.factory.ssn()
+            assert ssn.isdigit()
+            assert len(ssn) >= 10
+            assert len(ssn) <= 12
+
+        for _ in range(100):
+            dob_val = '{:02d}{:02d}{:02d}'.format(
+                self.factory.random_int(0, 99),
+                self.factory.random_int(1, 12),
+                self.factory.random_int(1, 31))
+            dob = self.factory.random.choice([None, dob_val])
+            gender = self.factory.random.choice([None, 'F', 'M', 'z'])
+            try:
+                ssn = self.factory.ssn(dob=dob, gender=gender)
+                assert ssn.isdigit()
+                assert len(ssn) >= 10
+                assert len(ssn) <= 12
+            except ValueError:
+                pass
 
 
 class TestPtBR(unittest.TestCase):
@@ -60,11 +87,11 @@ class TestPtBR(unittest.TestCase):
 
     def test_pt_BR_ssn(self):
         for _ in range(100):
-            self.assertTrue(re.search(r'^\d{11}$', PtProvider.ssn()))
+            self.assertTrue(re.search(r'^\d{11}$', self.factory.ssn()))
 
     def test_pt_BR_cpf(self):
         for _ in range(100):
-            self.assertTrue(re.search(r'\d{3}\.\d{3}\.\d{3}\-\d{2}', PtProvider.cpf()))
+            self.assertTrue(re.search(r'\d{3}\.\d{3}\.\d{3}\-\d{2}', self.factory.cpf()))
 
 
 class TestPlPL(unittest.TestCase):
@@ -99,4 +126,4 @@ class TestPlPL(unittest.TestCase):
 
     def test_ssn(self):
         for _ in range(100):
-            self.assertTrue(re.search(r'^\d{11}$', PlProvider.ssn()))
+            self.assertTrue(re.search(r'^\d{11}$', self.factory.ssn()))
diff --git a/tests/utils/__init__.py b/tests/utils/__init__.py
index cfdfe985..844dd6bd 100644
--- a/tests/utils/__init__.py
+++ b/tests/utils/__init__.py
@@ -2,7 +2,7 @@ from faker.utils.loading import find_available_locales
 from faker.utils.distribution import choice_distribution
 from faker.utils.datasets import add_dicts
 from faker.config import PROVIDERS
-from faker.generator import random
+from faker.generator import mod_random
 from faker.utils.loading import find_available_providers
 from faker.config import META_PROVIDERS_MODULES
 from importlib import import_module
@@ -25,7 +25,7 @@ class UtilsTestCase(unittest.TestCase):
             random_state = json.load(fh)
         random_state[1] = tuple(random_state[1])
 
-        random.setstate(random_state)
+        mod_random.setstate(random_state)
         samples = [choice_distribution(a, p) for i in range(100)]
         a_pop = len([i for i in samples if i == 'a'])
         b_pop = len([i for i in samples if i == 'b'])